Why is if statement returning False? - python

ALL_CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
HIDDEN = '^'`
def is_bonus_letter(lowercase_letter: str, phrase_puzzle: str,
current_view: str) -> bool:
"""Return True if and only if lowercase_letter is a bonus letter related
to phrase_puzzle and current_view.
>>> is_bonus_letter('k', 'talk', 't^l^')
True
>>> is_bonus_letter('l', 'love', 'l^v^')
False
"""
if ((lowercase_letter in ALL_CONSONANTS) and
(lowercase_letter in phrase_puzzle) and
(lowercase_letter in HIDDEN)):
return True
else:
return False
print(is_bonus_letter('k', 'talk', 't^l^')) # -> False
The output of is_bonus_letter('k', 'talk', 't^l^') should be True, but I keep getting False.
Why?

You're checking lowercase_letter in HIDDEN which is false since HIDDEN = '^' and lowercase_letter is t which does not exist in ^
Perhaps you meant to check lowercase_letter in current_view, as it would seem current_view is unused?
In general when you have two options, returning true or false, depending on many conditions, you can quickly find the answer by commenting out all of the conditions, then adding one back at a time until you pin point which one is causing it

Your program returns False because 'k' is not in 't^l^'. if you want it to return True, lowercase_letter would have to be 't' or 'l', OR you would have to edit your if statement. Right now, your program returns false because (lowercase_letter in HIDDEN) is false.

Related

Palindrome Function Issue

I was writing a function to see whether a string is a palindrome or not and came across an issue with my code. It seems to provide the right answer to most strings, but not to all!
Here it is:
def isPalindrome(string):
for letter in string:
if letter == string[(len(string)-1-string.index(letter))]:
return True
else:
return False
What is wrong with it? Thanks!
Use string slicing
string[start:stop:step]
string[::-1]
Starts from the end and moves towards the beginning, one step at a time.
In other words, slice the word, beginning at last index and move towards the first index.
See String Slicing
This is the most pythonic way to solve the problem.
def palindrome(word: str) -> bool:
return word == word[::-1]
palindrom('scarf')
>>> False # because scarf != fracs
palindrome('rotator')
>>> True # because rotator == rotator
Regarding your current implementation
Your function stops after the first letter because the return statement immediately stops the function and returns the value.
There are many ways to fix your code
Change return to yield, which will return a generator.
Iterating the generator, with list(), will then show True or False for each letter
The result is a palindrome if all() the items are True
This is not an efficient way to solve this problem.
def isPalindrome(string):
for letter in string:
if letter == string[(len(string)-1-string.index(letter))]:
yield True
else:
yield False
test = list(isPalindrome('rotator'))
print(test)
>>> [True, True, True, True, True, True, True]
print(all(test) == True)
>>> True
test = list(isPalindrome('scarf'))
print(test)
>>> [False, False, True, False, False]
print(all(test) == True)
>>> False
Currently you're returning true in cases where not the whole word matches. Only return False if any of the letters dont match, and return True at the end of the loop.
def isPalindrome(string):
for letter in string:
if not letter == string[(len(string)-1-string.index(letter))]:
return False
return True

Even and Odd numbers with recursion in Python

I'm trying to solve "is_even" and "is_odd" function in terms of the other with recursion. I don't understand HOW this function as written ever evaluates to False, or how anything that isn't 0 ever evaluates to True. I double-checked it in teamtreehouse.com workspaces to make sure it works at all, but I can't figure out HOW it works.
I understand that it's decrementing through recursion, but I don't understand how is_odd(x) works. If is_odd(x) just negates everything in is_even, why don't all numbers evaluate to True? Or False?
def is_even(x):
if x == 0:
return True
else:
return is_odd(x-1)
def is_odd(x):
return not is_even(x)
# Does this negate the function of is_even(x)?
# Does that negating mean returning False, or sending to else block?
# If the negating does automatically sends to the else block
# After we get here, do we ever land at True in is_even(x)?
# If not, how do we ever land at False?
print(is_even(1))
print(is_even(2))
print(is_even(3))
x = 0
is_even: True
x = 1
is_even:
is_odd(0):
is_even(0): True
not True: False
False
x = 2
is_even:
is_odd(1):
is_even(1): False
not False: True
True
x = 3
is_even:
is_odd(2):
is_even(2): True
not True: False
False
Let's take an example of the function is_even(1). What happens?
(1)
Enter in is_even(1)
Enter in is_odd(1-1), i.e. enter in is_odd(0)
Return not is_even(0). Enter in is_even(0)
x==0 -> this returns True
You have a not, remember in Step 3? So: not True -> False
is_even(1) = False
Let's now take an example of is_even(2). What happens?
(2)
Enter in is_even(2)
Enter in is_odd(2-1), i.e. enter in is_odd(1)
return not is_even(1)
We know from (1) that is_even(1) is False, so not False = True
Now with is_even(3)
(3)
Enter in is_even(3)
Enter in is_odd(3-1), i.e. enter in is_odd(2)
return not is_even(2)
We knot from (2) that is_even(2) is True, so not True = False
To your questions again:
Does this negate the function of is_even(x)?
Yes: not is_even(x) negates the result of is_even(x), as you saw in my examples.
Does that negating mean returning False, or sending to else block?
No. If the function is_even(x) returns True, not True returns False.
If the function is_even(x) returns False, not False returns True. So it negates the result of is_even(x)
After we get here, do we ever land at True in is_even(x)?
Since you always decrease the argument with (x-1), you will always eventually get to x=0, as you also saw in my examples.
What Sasha said is correct, however it does not fully illustrate the recursive call-stack.
x = 3
is_even(3):
return is_odd(2)
call is_even(2)
return is_odd(1)
call is_even(1)
return is_odd(0)
return is_even(0): True
return not True: False
return not False: True
return not True: False

Regex, test to see if characters other than exists

I'd like to use regex to see if any character other than a certain set exists.
For example, I'd like to test for the letters 'p', 'v', 'c' in a string. If any other characters are in the string, I want the test to return True. If only 'p', 'v', 'c' or a combination thereof exists, I want the test to return False.
'v' returns False
'pv' returns False
'pvc' returns False
'pd' returns True
'p(' returns True
'apvc' returns True
'xyz' returns True
How would I express this using re?
Thanks.
Use set(..)
if set(yourString) - set("pvc"):
return True
else:
return False
Edit: this should be turned into a single expression.
return set(your_string) - set('pvc')
I think this most straightforwardly captures your intent:
any(char not in 'pvc' for char in mystring)
It should be clear to anyone reading the code what you want to do.
import re
not (re.search('^[pvc]+$', string))
Not sure what you want if string is empty, and this one will return true.
import re
x = 'pvc'
regex = re.compile(r'[^p|v|c]')
if regex.search(x) is not None:
print True
else:
print False

See if string contains substring

I was looking for a way to write code that checks whether a certain string is a part of another string. I understand that it is easy to do when we have numbers, but I don't know how to do it with strings.
For example, I have this function
a = is_part("motherland", "land")
I need to know that "land" is a part of the word "motherland" (return True or False). Is it possible to check this?
UPDATE: How can I create a restriction when the second word always has to be in the end of the first one. For example, in case when I check whether "eight" is a part of "eighteen" it returns False because "eight" is not at the end of the first word
This should help:
>>> "land" in "motherland"
True
>>> "banana" in "motherland"
False
Here is a function that determines whether a string target is contained within another string some_string.
def is_part(some_string, target):
return target in some_string
>>> is_part('motherland', 'land')
True
>>> is_part('motherland', 'father')
False
>>> is_part('motherland', '')
True
If you don't like an empty string returning true, change the return statement to
return (target in some_string) if target else False
If, on the other hand, you need to implement it yourself:
def is_part(some_string, target):
if target:
target_len = len(target)
for i in range(len(some_string)):
if some_string[i:i+target_len] == target:
return True
return False

[Python]: When would you use the `any(x)` function?

I was going through the Python Manual for 3.4 when I came across a built in function that I didn't know about. The function was any(x).
The Python Manual said that this function "Return True if any element of the iterable is true. If the iterable is empty, return False."
They also wrote code that would be equivalent to this function.
def any(iterable):
for element in iterable:
if element:
return True
return False
What are the uses of this function?
You can use it to avoid multiple similar conditions, for example.
To check if a string contains a list of substrings, you can do:
str = 'Your cat is hungry.'
if 'cat' in str:
print 'Feed it!'
elif 'dog' in str:
print 'Feed it!'
elif 'hamster' in str:
print 'Feed it!'
...or you can do:
str = 'Your cat is hungry.'
pets = ['cat', 'dog', 'hamster']
if any(animal in str for animal in pets):
print 'Feed it!'
Update: if element: return True.
You are correct - if an element in the iterable has a value, it's True. In Python, basically if variable has a value, it's True - obviously, as long as the value isn't False. Run that example and look at the values and the conditions, maybe it helps more than explanations:
x = ' '
y = ''
z = False
if x:
print 'x is True!'
else:
print 'x is False!'
if x == True:
print 'x is True!'
else:
print 'x is False!'
if y:
print 'y is True!'
else:
print 'y is False!'
if z:
print 'z is True!'
else:
print 'z is False!'
Now back to any(): It takes any iterable, like a list, as an argument - and if any value of that iterable is True (hence the name), any() returns True.
There is also a function called all() - it's similar to any(), but only returns True if all values of the iterable are true:
print any([1, 2, False])
print all([1, 2, False])
True and False
It's been mentioned in a comment by #Burhan Khalid before, but the official docs about what's considered to be False should be mentioned here, too:
Truth Value Testing
the any function in python is just like a parallel connection of switches in a circuit if you like physics.
If any one of the switch is on ,(if element) the circuit will be completed and it will glow a bulb connected to it in a series connection.
lets take bulb in the parallel connection as shown in figure as circuits and
the bulb as the indicator bulb(the result of any)
for an instance , if you have a logical list of True and False,
logical_list = [False, False, False, False]
logical_list_1 = [True, False, False, False]
any(logical_list)
False ## because no circuit is on(True) all are off(False)
any(logical_list_1)
True ## because one circuit is on(True) remaining three are off(False)
or you can think of it as a connection of AND, so if any one of the value of the iterator is False, the Result will be False.
For the case of Strings, scenario is same, just the meaning has been changed
'' empty string -> False
'python' non empty string -> True
try this :
trial_list = ['','','','']
trial_list_1 = ['python','','','']
any(trial_list)
False ## logically trial_list is equivalent to [False(''), False(''), False(''), False('')]
any(trial_list_1)
True ## logically trial_list_1 is equivalent to [True('python'), False(''), False('') , False('')]
for the case of single non empty string any(non empty string) is always True
for the case of single empty string any(empty string is always False
any('')
False
any('python')
True
I hope this helps ,,

Categories

Resources