or condition in while loop python - python

Does or condition work in a while loop in python? I can't seem to make it work. This is the sample of how my code works.
newslot = 3
moved = False
while newslot > 0 or moved != True:
enabled = query something on the database where slot = newslot
if enabled:
print 'do something here'
moved = True
else:
newslot-=1
print 'slot disabled'
So when the newslot gets to value of zero it still proceeds to go inside the while loop.
I seem to be missing something here.

or is working as should be expected. A while loop will continue until its condition is false. If its condition is two separate conditions connected with an or, it will only be false when the two conditions are both false.
Your loop will continue repeating until moved is false and newslot is <= 0. I'm guessing you actually want to use and in this case, as you want the loop to stop once either condition is met.

Related

How to fix nested if/for loop

I'm attempting to change a flag to True when a nested dictionary has more than one key. The code currently counts the number of keys correctly, but it is not changing the flag to true.
I've done both the condensed version below and the more broken out version to no avail. I've also rearranged the statement in multiple ways, but cannot get it to trigger.
for page in sd:
chartcount = len(sd[page])
print '\n', 'Slide no.', page, '--There is/are', chartcount, 'Chart(s).'
[combinecheck is True if chartcount > 0 else False]
print combinecheck
I expect:
Slide no. 1 --There is/are 2 Charts.
True
I get:
Slide no. 1 --There is/are 2 Charts.
False
Not sure what are you trying to do with [] part. That looks like list comprehension (that would be useful if you would be creating a list, which you aren't. And you are not assigning that list anywhere either way.), you dont need that.
Instead put there:
combinecheck = chartcount > 0
[combinecheck is True if chartcount > 0 else False]
isn't assigning to combinecheck.
Try:
combinecheck = False
if chartcount > 0:
combinecheck = True

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.

Python: While Loop Check Throughout Loop if True

I have a very simple problem: I have made a while loop, and in the middle of it, set the initial condition to false. This, however, does not stop the loop and runs entirely through, (somewhat obviously,) until it attempts to unsuccessfully go through again. Here is a simplified construction of what I have.
while(a):
print("hi")
a = False
print("bye")
This returns:
hi
bye
Again I would like to only return hi; I want the loop to continually check if its satisfied.
Any help greatly appreciated.
Use:
return, or break
while a:
print('hi')
a = False
if not a:
break
print('bye')
In a function or loop, when something is returned, the function or loop terminates. You could also return True, or break which is a specific way to 'break' out of a loop.
Since the condition is true to start with (by design), the body of the loop will execute at least once. The fact you do something in the body of the loop to make the loop condition false doesn't stop the current iteration. It just means there won't be a next iteration after this one is done.
So if you want to get out in the middle of the current iteration, then you need to use break, return, or something more sophisticated like #inspectorG4dget's suggestion.
while(a):
print("hi")
a = False
if a:
print("bye")
OR
while(a):
for s in ["hi", "bye"]:
if a:
print(s)
if someCondition:
a = False

Python loop controler continue is not working properly

As I know, "continue" will jump back to the top of the loop. But in my case it's not jumping back, continue don't like me :(
for cases in files:
if ('python' in cases.split()):
execute_python_scripts(cases.split())
elif run_test_case(cases.split()):
continue
else:
logger("I am here")
break
In my case run_test_case() gives 1, 2, 3, 4 etc... But it always performs first(1) and jump to the else part. So I am getting the "I am here" message. It should not work like this. As I am using "continue", it should jump to the for loop.
Following is the run_test_case():
def run_test_case(job):
for x in job:
num_of_cases = num_of_cases - 1
test_type = x.split('/')
logger(log_file,"Currently "+ x +"hai!!")
if test_type[0] == 'volume':
backdoor = test_type[1].split("_")
if backdoor[0] == 'backdoor':
return get_all_nas_logs()
else:
if perform_volume_operations(x,num_of_cases) == False:
return False
else:
logger(log_file,"wrong ha!!")
Why is it always going to the else part, without jumping back to the for loop? Thanks in advance.
Here elif run_test_case(cases.split()): you are calling the run_test_case method, that will run your code to evaluate the result for the elif condition.
It only enters the block delimited by elif (in your case, continue), if the result of that method evaluates to True, otherwise it will jump to the else clause.
The problem is probably in your run_test_case code, that is never returning True, and so you'll never get the behavior that you're expecting.
It's hard to say without knowing exactly what you want to accomplish, but I'd say that you're missing a return True in the end of that code, meaning, if everything executes correctly right until the end, you want it to return True... but I'm only guessing here, you need to think about what that method is supposed to do.
In python an if or elif clause is evaluated for not only the True and False constants, but more generally for True-like and False-like values. None, for instance, is a false-like value, a non-empty string is a true-like value, etc.
Check this from the documentation on values that are considered true or false:
http://docs.python.org/library/stdtypes.html

Bubble sort error with nested (high scores) list - python

For my software major work I have to create a program. In summary, the high scores list needs to be sorted before it can be written to file. To do this, I am using a bubble sort and I can't use the inbuilt sort function. The text file that the data is being read from is stored in a nested list. The text file looks like this:
NameOne
10
NameTwo
15
NameThree
9
This is the bubble sort code I have but does not work:
b_not_sorted = True
while b_not_sorted:
counter = 0
b_not_sorted = False
for counter in range(len(highest_scores) - 1):
if highest_scores[counter] < highest_scores[counter + 1]:
b_not_sorted = True
highest_scores[counter], highest_scores[counter+1] = highest_scores[counter+1], highest_scores[counter]
counter = counter + 1
I need the scores to be sorted from highest to lowest. Any help would be greatly appreciated and you will be credited appropriately in my program credits :). Thanks.
Here's a hint:
Check how many times your outer while loop is running. It should be running more than once, correct? What will always happen that causes the loop to exit, no matter what?
Try going through the code line by line and seeing what happens at every point.
The statement b_not_sorted = False at the end of the outer loop results in the outer loop exiting after executing only once. You need to move that statement to another part of your code. Try changing the name of b_not_sorted to I_still_need_to_go_through_the_list in your head:
Obviously in the first line:
while I_still_need_to_go_through_the_list:
it should be True, since you haven't gone over the list at all. You don't know if it's in order or not.
and after the line:
if highest_scores[counter] < highest_scores[counter + 1]:
Of course then we still need to make another pass, since we just made a change to the list and need to make sure no further changes are needed.
But what if no changes are made? I_still_need_to_go_through_the_list should be False then. Hmmm. If we put I_still_need_to_go_through_the_list = False right before the for loop, then it will be False unless we make changes to the list, which is exactly what we want.
You're doing b_not_sorted = False right after the first iteration, but it shouldn't be there! The algorithm just stops before it finishes the sorting.
You should instead do b_not_sorted = True only if highest_scores[counter] < highest_scores[counter + 1]
Also, the swapping code can look much nicer in Python. Instead of using temp_var just do this:
highest_scores[counter], highest_scores[counter+1] = highest_scores[counter+1], highest_scores[counter]
Python style guide suggests that you shoudn't write == True or == False in if statements. Do it like this:
while b_not_sorted:

Categories