Differentiating 1 from 1*1 or 1**1 in python - python

If I have a function that receives an argument and I want that argument to return True if I put a correct tab but return False if I put anything else, even if the result in one of the elements is one (like 1+1-1 or 1*1), how do I do it?
What can I do to return False if I put on the argument a tab with an element like 1*1 or 1-1. In this case "tab" can have elements equal to 1,-1 and 0 so 1-1 should return False. Here is the function:
#lets consider this for tab. as you can see tab is a tuple with 3 tuples, each with 3 elements
tab = ((1,-1,1),(0,-1,0),(-1,1,1))
tab2 = ((1,-1,1),(1-1,-1,0),(-1,1,1))
def eh_tabuleiro(tab):
if len(tab) != 3:
return False
else:
for row in tab:
if len(row) != 3:
return False
else:
for element in row:
if element not in (-1, 0, 1):
return False
return True
In this case if tab, eh_tabuleiro(tab) returns True (as it should) but eh_tabuleiro(tab2) also returns True and it should be False. What can I do?
Thanks in advance guys!

Related

What's wrong with my code?Valid Palindrome 2- Leetcode 680

Given a string s, return true if the s can be palindrome after deleting at most one character from it.
Example 1:
Input: s = "aba"
Output: true
Example 2:
Input: s = "abca"
Output: true
Explanation: You could delete the character 'c'.
Example 3:
Input: s = "abc"
Output: false
For this problem in leetcode my code has passed 462/469 test cases:
Following is the test case for which my code is failing the test.
"aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga"
My code is:
class Solution:
def validPalindrome(self, s: str) -> bool:
skip=0
l,r=0,len(s)-1
while l<r:
if s[l]==s[r]:
l+=1
r-=1
elif s[l]!=s[r] and skip<1 and s[l+1]==s[r]:
l+=1
skip=1
elif s[l]!=s[r] and skip<1 and s[r-1]==s[l]:
r-=1
skip=1
else:
return False
return True
What is the problem with my code?
Note: in this string the output should be true, mine returns false
From left there are characters 'lcup' and from right there are characters 'lucup'
My code is supposed to skip the letter u from right side and continue.
"aguokepatgbnvfqmgm**lcup**uufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuu**pucul**mgmqfvnbgtapekouga"
Another example: It returns true for the following string:
s='adau'
Skips letter 'u' as expected.
However when I use the example according to the test case string that failed, it returns False. s= 'cuppucu'
It should skip first u from the right side and return True but it doesn't.
However as soon as I replace that last letter 'u' with letter 'a' it skips the letter 'a' and returns True. What's the problem here?
I over-complicated this in my first answer. I thought that you had to skip a particular character multiple times. As others have pointed out, that isn't true. So you have a solution from someone else, but you wanted to know how to change your code to always do the right thing. One way would be to run your algorithm twice. The first time, you only consider if you can skip a character on the left side of the input string as you're walking over it. For the second call, you only consider skipping a character on the right side. For cases like the one you ran into here where you could choose to skip either character, but only one will produce a positive result, well then if you try both cases, one or the other will always succeed when it should.
So here's that simple change you can make...modifying your function only slightly, and then calling it twice.
class Solution:
def _validPalindrome(self, s: str, choose_first: bool) -> bool:
skip = 0
l, r = 0, len(s) - 1
while l < r:
if s[l] == s[r]:
l += 1
r -= 1
elif choose_first and s[l] != s[r] and skip < 1 and s[r - 1] == s[l]:
r -= 1
skip = 1
elif not choose_first and s[l] != s[r] and skip < 1 and s[l + 1] == s[r]:
l += 1
skip = 1
else:
return False
return True
def validPalindrome(self, s: str) -> bool:
return self._validPalindrome(s, False) or self._validPalindrome(s, True)
def main():
inp = "aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga"
print(Solution().validPalindrome(inp))
main()
Result:
True
This should pass for all the cases for which your original code passed.
Imagine the string 'abbab'. First you check index 0 and 4 with the values "a" and "b". They are not the same, but the "b" at index 1 matches the "b" at index 4. So you move forward to 1 and 4. Next is 2 and 3 and those are "b" and "a" and those don't match too. End of the story.
abbab
l r
abbab
l r
abbab
lr
-> False
Now let's switch around the elif blocks. Again you check index 0 and 4 first. They are not the same, so you now change the right index first and see that 0 and 3 are both "a". The next comparison is at indexes 1 and 2 with "b". Finished. Found a match.
abbab
l r
abbab
l r
abbab
lr
-> True
You didn't ask for it but here is a working solution with a different approach.
class Solution:
def generate_strings(self, s):
yield s, s[::-1]
for pos in range(len(s)):
t = ''.join(c for i, c in enumerate(s) if i != pos)
yield t, t[::-1]
def validPalindrome(self, p):
return any(x == y for x, y in self.generate_strings(p))

Isinstance function to check the elements given fits in my matrix

I want to create a function that checks if the given tab fits or not. My matrix should be a 3x3 with 3 tuples, each with 3 integers.
I want this interaction to happen:
>>> tab = ((1,0,0),(-1,1,0),(1,-1,-1))
>>> tabuleiro(tab)
True
>>> tab = ((1,0,0),(’O’,1,0),(1,-1,-1))
>>> tabuleiro(tab)
False
>>> tab = ((1,0,0),(-1,1,0),(1,-1))
>>> tabuleiro(tab)
False
All I have right now is:
def tabuleiro(tab):
return isinstance(tab, tuple) and len(tab) == 3 and \
all((isinstance( l, tuple) and len (l) == len(tab[0])) for l in tab) and len (tab[0]) == 3 and \
(....)
This is probably easier to read and reason about if you break it into one function for the group and another function for each member of the group. Then you could do something like:
def tab_is_valid(tab, valid_size=3):
''' is an individual member valid'''
return len(tab) == valid_size and all(isinstance(n, int) for n in tab)
def tabuleiro(tab):
''' is the whole structure valid '''
return all((
isinstance(tab, tuple),
len(tab) == 3,
all(tab_is_valid(t) for t in tab),
))
tabuleiro(((1,0,1),(-1,1,0),(1,-1,-1)))
# True
tabuleiro(((1,0,1.6),(-1,1,0),(1,-1,-1)))
# False
tabuleiro(((1,0),(-1,1,0),(1,-1,-1)))
#False
tabuleiro(((1,0, 1),(-1,1,0),(1,-1,-1), (1, 1, 1)))
# False
In python3.10 and above, you can use pattern matching:
def tabuleiro(tab):
match tab:
case (int(),int(),int()),(int(),int(),int()),(int(),int(),int()):
return True
case _:
return False
print(tabuleiro(((1,0,1),(-1,1,0),(1,-1,-1))))
# True
print(tabuleiro(((1,0,1.6),(-1,1,0),(1,-1,-1))))
# False
print(tabuleiro(((1,0),(-1,1,0),(1,-1,-1))))
#False
print(tabuleiro("string is not a tuple"))
# False
The line case _: does not change the value of variable _ (If I use another variable name, the value of this variable whould be the value of tab).
This line and the identation of last line return false are here not necessary, but I keep them for sake of readability.

Given a list of ints, return True if the array contains a 3 next to a 3 somewhere

I want to creates a function that returns True if a list contains two consecutive 3 and false if not.
when using this code it doesn't work:
def has_33(x):
for i in range(len(x)-1):
if x[i:i+2] == [3,3]:
return True
else:
return False
But with this it works:
def has_33(x):
for i in range(len(x)-1):
if x[i:i+2] == [3,3]:
return True
return False
For me it's the same thing can you explain to me why plz
In the top code you only check the first 2 indices. In the bottom code you're checking the whole array. Here's why:
In the top code you have an else condition, which means that on the first iteration either the if-condition is true (i.e. the first and the second element of the list are 3) or you will go into the else condition. In either case, you're hitting a return statement after checking just the first 2 elements.
In the bottom code, you only return if you find something, or once you've finished the whole loop
I've added some print statements to both your functions. You can run this code and see the output to help you understand what's happening:
def has_33_incorrect(x):
print("\nRunning the incorrect function")
for i in range(len(x)-1):
print("Checking indices {} and {}".format(i, i+1))
if x[i:i+2] == [3,3]:
print("indices contain 2 consecutive 3's. Returning true")
return True
else:
print("indices don't contain 2 consecutive 3's. Returning false")
return False
def has_33_correct(x):
print("\nRunning the correct function")
for i in range(len(x)-1):
print("Checking indices {} and {}".format(i, i+1))
if x[i:i+2] == [3,3]:
print("indices contain 2 consecutive 3's. Returning true")
return True
print("Did not find consecutive 3's. Returning false")
return False
list = [1, 2, 4, 5, 6, 3, 3, 2, 5]
has_33_incorrect(list)
has_33_correct(list)
One more solution with any python builtin:
def has_33(l):
return any(l[i+1] == l[i] == 3 for i in range(len(l) - 1))
This code works since if the if condition is false it doesn't return anything, yet in the first function you showed it returns false and exits the function. You shouldn't return anything until you find that its true somewhere, only after you've iterate over the entire list then and only then should you return False
def has_33(x):
for i in range(len(x)-1):
if x[i:i+2] == [3,3]:
return True
return False
You can iterate over the list directly.
def has_33(x):
current = None
for item in x:
if current == item == 3:
return True
current = item
return False
If you ever find both current and item are equal to 3, you can return True immediately. Otherwise, you will return False when the loop exits naturally.
If you loop through adjacent entries at the same time, you can compare:
def adjacent_threes(x):
for a, b, in zip(x[:-1], x[1:]):
if a == b == 3:
return True
return False
Try this ,it's simple:
def has_33(nums):
for i,num in enumerate(nums):
if nums[i]==3 and nums[i+1]==3:
return True
return False
python code as follows :
def has_33(nums):
my_list = []
y =len(nums)-1
for x in range(0,y) :
if nums[x] == 3 and nums[x+1] == 3:
my_list.append(1)
else :
my_list.append(0)
print(my_list)
if 1 in my_list:
return True
else :
return False

Checking if value in list. Returning within or outside loop?

I'm new to Python programming. I'd like some guidance as to the reason behind the output. I was just doing some exercise online and came across a problem which I could not understand. The code goes like this:
def dataset(data,n):
for value in data:
if n == value:
return True
else:
return False
print(dataset([1,5,8,3], 3))
print(dataset([1,5,8,3],-1))
The output would be False, False which is the incorrect answer.
After some tinkering, I found out the problem. The correct code is as follows:
def dataset(data,n):
for value in data:
if n == value:
return True
return False
print(dataset([1,5,8,3], 3))
print(dataset([1,5,8,3],-1))
The output is True, False which is the correct answer.
So my question is why the different output with just a different putting of the return Falseand else: return False ?
In the first case, you are iterating through the list and then returning either True or False depending on whether the first item matches the input value. Since in your data the first element never matches the input, both return False.
In the second case, the function only returns if any list item matches the input. The loop iterates through all the elements until one is matched. If not, it returns False.
I know the question has already been answered but as you're new to Python I thought I'd give you a little extra :-)
def dataset(data,n):
return n in data
This will work. It simply checks if n is in the list or not and returns either True or False
Your first answer stops after the first item, the false branch runs for each item, whereas the second only runs the false branch after all the items have been tried.
If you change the final code to this:
def dataset(data,n):
print("checking", data, n)
for value in data:
print("trying", value)
if n == value:
print("Found")
return True
print("Giving up")
return False
print(dataset([1,5,8,3], 3))
print(dataset([1,5,8,3],-1))
You can see it tries every item, as it outputs this:
('checking', [1, 5, 8, 3], 3)
('trying', 1)
('trying', 5)
('trying', 8)
('trying', 3)
Found
True
('checking', [1, 5, 8, 3], -1)
('trying', 1)
('trying', 5)
('trying', 8)
('trying', 3)
Giving up
False
Whereas the first code only tries the first item:
def dataset(data,n):
print("checking", data, n)
for value in data:
print("trying", value)
if n == value:
print("Found")
return True
else:
print("Giving up")
return False
print(dataset([1,5,8,3], 3))
print(dataset([1,5,8,3],-1))
Which outputs:
('checking', [1, 5, 8, 3], 3)
('trying', 1)
Giving up
False
('checking', [1, 5, 8, 3], -1)
('trying', 1)
Giving up
False
When you have else: return false you program would return False whenever it encounters a element that is not n .
However, if you put it at the end of the function, the statement return False would only execute when none of the statement n==data that were previously executed are true because the function would no longer be executed after the return statement. When none of n == data is true, it means n in not in data.
This loop
for value in data:
if n == value:
return True
else:
return False
Is logically equivalent to this one line
return n == data[0]
In other words, you've returned and exited the loop / function after the very first element
Your other solution, which is logically equivalent to return n in data, or return any(n == x for x in data) will iterate over the whole list, and give you the value after all values have been checked. (I think these two alternatives will short circuit when a match exists, though)

Recursive function seems to be fine, but won't return False

So the function should check if a list is symmetric; if the list is empty or has one integer, it is symmetric.
Otherwise the function should check if the first and last integers are the same and go on recursively. If not, return False.
The code seems right, but I can't figure out what's wrong and why it won't return False.
def symm(lst):
t = len(lst)
if t == 0 or 1:
return True
if t>1:
if lst[0] == lst[-1]:
return symm(lst[1:-2])
else:
return False
print symm([6,6,6,6,7])
if t == 0 or 1: is always true since this is read as if (t == 0) or (1): and 1 is always going to be true.
Change to: if t in [0,1]: or simply if len(lst) < 2:

Categories