Explanation of While Loop Using the Logical Operator "not" - python

Code from "Think Like a Computer Scientist: Python"
def find(astring, achar):
ix = 0
found = False
while ix < len(astring) and not found:
if astring[ix] == achar:
found = True
else:
ix = ix + 1
if found:
return ix
else:
return -1
I've run this through CodeLens in all variations of location of not and original value for found, but cannot wrap my head around the way Python handles its conditions in this form. Please point out where my train of thought goes wrong or what I miss:
If found = False, then not found = True when found = True.
The condition is set to not found so the loop will iterate. (I set the condition to found and it does not iterate. So while loops must only iterate for True values). Once achar is found in astring, found = True. What is the logic behind this closing the loop? Where is my misunderstanding of the use of not?

I think you should consider the Not operator as an inverter. The logic table would be:
A | Not A
T | F
F | T
So when Found is False it is actually True and when it is True it is False.
The conditional statement for the while loop works as while True - execute code, while false exit code.
Looking at the conditional, it is an and operation where both operations have to be True to be True, if you look up the and gate truth table you can learn more about it.
Basically, both 'ix < len(astring) and not found' have to be true for the loop to.
Hope this helps

Related

Please explain what "while True !=0 mean

Is while True !=0: valid , if so what does it mean? Because in my program using that or "while True" (by itself) provides the same output. I can't remember why I used it before in my code.
Thanks in advance.
This is used to create infinite loops (or loops that exit via a break or return statement within the loop body). The standard way to do this is:
while True:
...
The other version you showed, while True != 0:, is equivalent, but needlessly convoluted. It works because, when treated as an integer, True has the value 1, so it's equivalent to while 1 != 0: which, in turn, is equivalent to while True:, which is the most direct way to express it.
Yes, while True != 0: is valid and it has the same meaning as while True: which you should use from now on.
This works because int(True) evaluates to 1.
It's simple, true != 0 => 1 != 0 is always 1 (true) .

Is this function logical or am I over thinking? Loop errors for finding even number

Which code segment should replace the statement pass in the function hasEvenNumber which returns True if n contains an even number and False otherwise?
def hasEvenNumber(n):
for i in n:
pass # Replace this section with below options
return result
The question screenshot
This is an actual university exam question. I find it very badly structured and since my classmates are new too, nobody dared to voice out fearing to make a fool of themselves.
Firstly n was not given, but judging that n will be used in a for loop. n therefore, would be an iterable. I think none of the 4 options applies, but please advise me if I'm wrong.
Option 1:
if i % 2 == 0:
result = True
else:
result = False
This will only work if iterable only contains 1 item e.g [1,2,1] will not work since the result of 2 as even number that should return true will be replaced as the loop proceed to next iteration.
[1,2,1,1] False # Wrong, should be true
[1,1,1,2] True
[2] True
Option 2:
if i % 2 == 0:
result = True
break
else:
result = False
break
Worse than above, this will only iterate the first item and break regardless.
[1,2,1,1] False # Wrong, should be true
[1,1,1,2] False # Wrong, should be true
[2] True
Option 3:
if i % 2 == 0:
result = True
break
Function will have runtime error if no even number is found, the variable result will not be assigned.
[1,2,1,1] True
[1,1,1,1] Runtime Error
[2] True
[1] Runtime Error
Option 4:
if i % 2 != 0:
result = False
break
Same as above, runtime error. No variable will be assigned if all even numbers.
Personally, as the question asked to check if n contains even number. I would have written something like this.
# Break and exit loop once even number is found. Otherwise continue.
if i % 2 == 0:
result = True
break
else:
result = False
Unfortunately, this is not an option. Apologies if this is the wrong place to post this, but any advice would be gladly appreciated, and could possibly change the fate our my current school cohort.
Yes, you are right and little bit overthinking.
Third option is right and it is kinda assumed here that result is set to False in the beginning.
Also, your solution can be optimised by declaring result = False once in the beginning and then you can eliminate the else block completely.
If you want it to end when an even number is found, option 3.

I get an error when I end the if statement with a concluding else statement

I wrote this Python code that would check a list and return True if two items in the list next to each other are of the same value:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
Result 1:
>>> samer([1,3,44,5,5,8])
False
This is where I'm puzzled because I feel it should return True.
Result 2:
>>> samer([3,3,49,93,5,8])
True
It only returns True if the first and second number in the list is True.
The solution:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
return False
The above code works well, so my question is since the else statement indented under the if condition's purpose is to return False if no number in the list is next to each other in the process of the for loop, why do I still get False in Result 1?
Is it that it doesn't loop again after checking the first two boxes and why is that since it's the purpose of the for loop to go over each iteration and then check for the conditions?
When a function returns, that's it. The function is done, over, finished..
Since you're returning either true or false when checking each and every element, you really only check the first time through the loop (elements one and two), as you observe.
You should return true if a match is found and only return false at the end, when you've checked everything and, therefore, no matches are found. That code is already in your question, the bit under The solution.
So to chip in here, once that first iteration check occurs, we know that it's going to be returning False as the first two elements are not the same and the program ends there. If you want to really see that this is the case, make use of print() built-in function to see what's going on everytime the element is iterated within the for loop:
Like this:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
print(True)
else:
print(False)
### adding a main method is always a good idea for clarity.
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is this:
False
False
False
True
False
See it returned True for the 3th element as they are equal and next to each other.
But with the way you had it structured in the first example it does return False as it hit the roadblock once it checked and saw that the first iteration were not equal to each other and thus returned False.
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is:
False
With your solution approach which is great, the loop only 'terminates' when it really cannot find a match (same two numbers), it will return False without depending on a else statement. So if it finds a match then it will return True which is does and then stops iterating and exits the program.

If all elements match requirement not using "if all"

I am learning python with a book: The exercise is to make a program that print True if all numbers in a list all odds.
I get it whit this approach
if all(x % 2 == 1 for x in list):
But the 'if all' approach is not yet explained. They only use while, if,for and booleans in the examples. Furthermore, seems to be a reflexive exercise about it is possible to do it, maybe not. It is possible to do it using the basic tools of above?
If you look at the docs: https://docs.python.org/3/library/functions.html#all
all(iterable) .
Return True if all elements of the iterable are true (or if the iterable is empty). Equivalent to:
def all(iterable):
for element in iterable:
if not element:
return False
return True
So if all(x % 2 == 1 for x in li): roughly translates to
def are_all_odds(num_list):
#Flag to keep track if we encounter an even number
flag = True
for num in num_list:
#Once we encounter a even number, we break the for loop
if num % 2 != 1:
flag = False
break
#Return the flag
return flag
We can test this function by doing
print(are_all_odds([1, 2, 3, 4]))
#False
print(are_all_odds([1, 3, 5]))
#True
Also just a suggestion, list is a python builtin keyword, so don't use it in variables :)
Yes, it is possible.
The Python code you wrote is very idiomatic, keep up that good work.
To see how to do it differently, you can look at programming languages that are less advanced, such as C. That is a very basic programming language which lacks the features for this if all statement. Searching for "c all elements array true" should give you the code you are looking for. For such a simple piece of code, it's easy to translate the code back into Python.

python if/else logic explained please

I have a really basic if/else logic question for Python. An exercise in the book required me to write a function that takes a list of integers are returns True if the list contains all even numbers and False if it doesn't.
I wrote:
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
else:
return True
This code always returns True. Why is that? Doesn't the code see the -1 during the loop of all the values of the list and returns the False?
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
return True
The book gives the answer of this. Why does this work and mine doesn't?
Pay close attention to where that else is placed. Indentation and nesting matters here!
In your first example, it will return True on the first element that satisfies your condition because your first if check fails.
In your second example, it will return True after all elements have been iterated through and a return value hasn't been produced.
The first function checks the first number only, since it returns something as soon as the for loop starts.
By the way, you can but should not use list as an argument or a variable name, since it is a keyword.
I strongly recommend writing a print statement to output x before both of your return statements. It will help you understand the flow of the code.
The short answer is that only the first element is being checked by your code, and the function returns True or False based on that value.
In the book solution, any failure causes a return of False, but the loop simply continues otherwise. Only if all elements are checked without failure does the return True reached.

Categories

Resources