Could you please help me why the second method does not work in the class even though it works separately?
the question is
Develop a SuperStr class that inherits the functionality of the standard str type and contains 2 new methods:
a. is_repeatance(s) method, which takes 1 argument s and returns True or False depending on whether the current row can be obtained by an integer number of repetitions of the string s. Return False if s is not a string. Assume that the empty string contains no repetitions.
b. is_palindrom() method, which returns True or False depending on whether the string is a palindrome. Ignore the case of characters. The empty string is considered a palindrome.
my code:
class SuperStr:
def __init__(self, main_str):
self.main_str= main_str
def is_repeatance(self, s):
string = self.main_str
count = 0
is_repeated = False
if string == '':
return False
else:
for i in range(0, len(string)):
if string[i] == s:
count = count + 1
if count == 2:
is_repeated = True
return is_repeated
break
return is_repeated
def isPalindrome(str):
if str == '':
return True
else:
for i in range(0, int(len(str) / 2)):
if str[i] != str[len(str) - i - 1]:
return False
return True
str = SuperStr("welcome to the world of python programming")
print(str.is_repeatance('s'))
print(str.isPalindrome('saas'))
the result is https://drive.google.com/file/d/1dHXK8RJs7vlRovULrUPS5uxRkX_oDNRO/view?usp=sharing
the second method does not work but the first does
even though it works this way if it is alone
https://drive.google.com/file/d/1SBFnQ6OeDGtoTvo98SHeSdIbks8BTXnT/view?usp=sharing
What Avinash said in the comments should fix your problem. You need to include self in the method definition. e.g.
def isPalindrome(self, s):
if s == '':
return True
else:
for i in range(0, int(len(s) / 2)):
if s[i] != s[len(s) - i - 1]:
return False
return True
The error you have is...
TypeError: isPalindrome() takes 1 positional argument but 2 were given
The error is saying that isPalindrome() has been defined with 1 positional argument. In your case this is the str in the def isPalindrome(str):. When you call it using the instance object str.isPalindrome('saas'), python adds the object itself as the first argument, so the method is called with 2 arguments. The object str and the value 'saas'.
Notice also that your def is_repeatance(self, s): method has self as an argument and works fine.
Related
Here is my python code:
class Solution():
def isPalindrome(self):
return str(self.x) == str(self.x)[::-1]
s1 = Solution()
s1.x = 121
s1.isPalindrome()
It checks to see if the input is a palindrome. I want to create a new object that has the x value 121 and when I execute the isPalindrom function, I want it to return either a true or false boolean answer.
Currently when I run this program, nothing gets outputted. I am a bit lost as to where to go from here, would appreciate help.
Just print out the return value of isPalindrome(), because if you have a line with only a return value (this case being a boolean), the compiler won't know what to do with it.
class Solution():
def isPalindrome(self):
return str(self.x) == str(self.x)[::-1]
s1 = Solution()
s1.x = 121
print(s1.isPalindrome())
You're not telling the program to print anything. Try using print to make it reveal the answer.
Along with printing results we can also make class more pythonic.
class Solution:
def __init__(self):
self.input = None
def is_palindrome(self):
if isinstance(self.input, str):
return self.input == self.input[::-1]
print("Error: Expects str input")
return False # or leave blank to return None
s1 = Solution()
print(s1.is_palindrome())
s1.input = "121"
print(s1.is_palindrome())
output
Error: Expects str input
False
True
The main idea here is divide number. let's take number 122. First of all you need store it in a variable, in this case r_num. While loop is used and the last digit of the number is obtained by using the modulus operator %. The last digit 2 is then stored at the one’s place, second last at the ten’s place and so on. The last digit is then removed by truly dividing the number with 10, here we use //. And lastly the reverse of the number is then compared with the integer value stored in the temporary variable tmp if both are equal, the number is a palindrome, otherwise it is not a palindrome.
def ispalindrom(x):
r_num = 0
tmp = x
while tmp > 0:
r_num = (r_num * 10) + tmp % 10
tmp = tmp // 10
if x == r_num:
return True
return False
I need to write this iterative function to do the same thing but it must be recursive.
def task1(string: str):
for i in range(len(string)):
if string[i] != string[len(string) - i - 1]:
return False
return True
This is what i tried but it does not work.
def task1_recursion(string: str):
print(string)
if len(string) > 1:
if string[0] == task1_recursion(string[1::1]):
return True
else:
return False
else:
return string
My code seems to one the last recursion return string "" and that makes it to return False.
Just check the tip and the tail, continue with the string without them:
def task1_recursion(string: str):
# recursion base condition (exit condition)
if len(string) <= 1:
return True
# unpack values
first, *_, last = string
# check if they are different
if first != last:
return False
# if not continue checking the remaining string
return task1_recursion(string[1:-1])
If I understand correctly you want to check if a string is symmetric with the code in task1. My solution is below:
def fct(s: str, i: int):
if len(s) <= 1 or i == len(s):
return True
return s[i] == s[len(s) - 1 - i] and fct(s, i + 1)
I tested and fct produces the same result as task1. It needs an additional parameter for the index though. But you can wrap it inside another function if you want the parameter to include only the input string. i is always set to 0 when you call the function, e.g. fct("ABCCBA", 0).
I have an assignment, I have to make a python code that checks whether a string is a palindrome using a recursive function that returns a boolean, but I am not allowed to use reversed slicing nor loops, and I am not allowed to change the function format, here's my code but it returns True all the time
def is_palindrome(s):
res = []
s = ['']
if len(s) < 2:
return True
else:
rev_s = is_palindrome(s[1:]) + s[0]
res.append(rev_s)
if res == s:
return True
return False
You can check if the first and the last character of the given string are the same and then recursively check if the remaining string is a palindrome instead:
def is_palindrome(s):
return len(s) < 2 or s[0] == s[-1] and is_palindrome(s[1:-1])
I'm not sure if this counts as 'changing the function format', but here's my stab at a recursive version without slices:
def is_palindrome(s):
def is_palindrome_r(i, j):
if j <= i:
return True
if s[i] != s[j]:
return False
return is_palindrome_r(i + 1, j - 1)
return is_palindrome_r(0, len(s) - 1)
The inner function, is_palindrome_r, is the recursive function that takes two indexes, i and j. The last line sets the initial positions for these two indexes at 0 (the start of the string) and len(s) - 1 (the end of the string) and proceeds with the recursive logic. The recursive function has two exit conditions:
if j <= i we've reached the center of our palindrome. If we've gotten this far, we know all the other pairs of characters match and we don't need to do any more comparisons.
if the two characters pointed to by i and j do not match, it's definitely not a palindrome and we don't need to do any more comparisons.
Otherwise we don't yet know if the sequence is fully palindromic, so we we move our indexes one step inward (i + 1, j - 1) and go back to step 1.
No slicing used, just maintain the indices through the recursive calls
def is_palindrome(s):
return helper(s, 0, len(s)-1)
def helper(s, i, j):
if (i >= j):
return True
return s[i] == s[j] and helper(s, i+1, j-1)
If the mentioned function signature def is_palindrome(s) is the signature given by your teacher then no issue and there is no need to pass any extra parameter to achieve the goal.
Your teacher (or the one gave you this task is awesome) just wanted t check how do you handle this with only 1 parameter.
The concept is very simple, just change the type of argument (to list with 3 values) in second recursive call.
def is_palindrome(s):
if type(s) is str:
l = len(s)
if l == 0 or l == 1:
return True
else:
return is_palindrome([s, 0, -1])
else:
string, start, end = s # s is list here
if string[start] != string[end]:
return False
else:
if(start + 1 >= end - 1):
return True
return is_palindrome([s, start + 1, end - 1])
def main():
string1 = "abcba"
string2 = "abcde"
string3 = "AxxA"
print(is_palindrome(string1)) # True
print(is_palindrome(string2)) # False
print(is_palindrome(string3)) # True
main();
The following is not what you're looking for but may be you'll be looking for that in future.
>>> def is_palindrome(s):
... if s == "".join(reversed(s)):
... return True
... else:
... return False
...
>>> is_palindrome("ABA")
True
>>>
>>> is_palindrome("ABC")
False
>>>
>>> is_palindrome("XXZZXX")
True
>>>
>>> is_palindrome("##7")
False
>>>
>>> is_palindrome("1###1")
True
>>>
Thank you.
How can I find the position of a substring in a string without using str.find() in Python? How should I loop it?
def find substring(string,substring):
for i in xrange(len(string)):
if string[i]==substring[0]:
print i
else: print false
For example, when string = "ATACGTG" and substring = "ACGT", it should return 2. I want to understand how str.find() works
You can use Boyer-Moore or Knuth-Morris-Pratt. Both create tables to precalculate faster moves on each miss. The B-M page has a python implementation. And both pages refer to other string-searching algorithms.
I can't think of a way to do it without any built-in functions at all.
I can:
def find_substring(string, substring):
def starts_with(string, substring):
while True:
if substring == '':
return True
if string == '' or string[0] != substring[0]:
return False
string, substring = string[1:], substring[1:]
n = 0
while string != '' and substring != '':
if starts_with(string, substring):
return n
string = string[1:]
n += 1
return -1
print(find_substring('ATACGTG', 'ACGT'))
I.e. avoiding built-ins len(), range(), etc. By not using built-in len() we lose some efficiency in that we could have finished sooner. The OP specified iteration, which the above uses, but the recursive variant is a bit more compact:
def find_substring(string, substring, n=0):
def starts_with(string, substring):
if substring == '':
return True
if string == '' or string[0] != substring[0]:
return False
return starts_with(string[1:], substring[1:])
if string == '' or substring == '':
return -1
if starts_with(string, substring):
return n
return find_substring(string[1:], substring, n + 1)
print(find_substring('ATACGTG', 'ACGT'))
Under the constraint of not using find, you can use str.index instead, which returns a ValueError if the substring is not found:
def find_substring(a_string, substring):
try:
print(a_string.index(substring))
except ValueError:
print('Not Found')
and usage:
>>> find_substring('foo bar baz', 'bar')
4
>>> find_substring('foo bar baz', 'quux')
Not Found
If you must loop, you can do this, which slides along the string, and with a matching first character then checks to see if the rest of the string startswith the substring, which is a match:
def find_substring(a_string, substring):
for i, c in enumerate(a_string):
if c == substring[0] and a_string[i:].startswith(substring):
print(i)
return
else:
print(False)
To do it with no string methods:
def find_substring(a_string, substring):
for i in range(len(a_string)):
if a_string[i] == substring[0] and a_string[i:i+len(substring)] == substring:
print(i)
return
else:
print(False)
I can't think of a way to do it without any built-in functions at all.
Im trying to write a recursive function that gets as an input a string and a char. the function return the first index appearance of the char in the string. If the char doesnt appear it returns None.
I have a problem only with returning None. In my case when the char isnt in the string the function throws an error, any advice?
def char_first_index(s,c):
if len_rec(s)==0:
return None
if s[0]==c:
return 0
return 1+ char_first_index(s[1:],c)
You are creating a new slice at each iteration, and you have to add 1 for each recursion. Instead, recurse on the index:
def char_first_index(s, c, index = 0):
if len(s) == index:
return None
if s[index] == c:
return index
return char_first_index(s, c, index + 1)
If the character is not in the input, your function tries to perform 1+None, hence the error. Try this instead:
def char_first_index(s,c):
if len_rec(s)==0:
return None
if s[0]==c:
return 0
answer = char_first_index(s[1:],c)
if answer is not None:
return 1+answer
else:
return answer
Firstly I'm assuming len_rec is a recursive function that gets the length of the string; you haven't written it so I've just changed it to len() for testing.
Secondly, I'm not sure how this function is supposed to handle the character not being in the string, as that will mean trying to add None to a number.
Here is an amended function that still uses your count idea, but handles the case of a None being returned:
def char_first_index(s,c):
if len(s)==0:
return None
elif s[0]==c:
return 0
else:
count = char_first_index(s[1:], c)
if count != None:
return count + 1
else:
return None