class String(object):
def __init__(self, text):
self.text = text
def __repr__(self):
return "{}".format(self.text)
def reverse(self):
return self.text[::-1]
def isPalindrome(self):
return (self.reverse(self.text) == self.text)
def main():
string = String(input("Write a String: "))
if(string.isPalindrome()):
print("The string {{}} IS a Palindrome".format(string))
else:
print("The string {{}} is NOT Palindrome".format(string))
I have this classe that represents a String and i want to check is a object is a palindrome by calling the method isPalindrome. But when i call the string.isPalindrome i get this error:
Traceback (most recent call last):
File "palindrome.py", line 23, in <module>
main()
File "palindrome.py", line 17, in main
if(string.isPalindrome()):
File "palindrome.py", line 12, in isPalindrome
return (self.reverse(self.text) == self.text)
TypeError: reverse() takes 1 positional argument but 2 were given
The error comes from this line:
return (self.reverse(self.text) == self.text)
change it for this:
return (self.reverse() == self.text)
self can be really confusing, here is a really good article to understand how it works. Just so you understand, look at reverse() definition:
def reverse(self):
return self.text[::-1]
As you can see, self.text is already assigned. No need to pass it to the function when calling it.
Related
i am working with
inheritence,here i got output for single inheritence but multiple inheritence showing error.so please help me.I don't have any knowledge about mro in python.please give me good advice.
class Player:
def __init__(self,name,country):
self.name=name
self.country=country
def info(self):
return self.name+":"+self.country
class Ipl(Player):
def __init__(self,name,country,team):
Player.__init__(self,name,country)
self.team=team
def info_ipl(self):
return self.info()+"\nIpl team:"+self.team
x=Ipl("Suresh Raina","India","csk")
print(x.info_ipl())
class Carrier:
def ___init__(self,wicket,run):
self.wicket=wicket
self.run=run
def disp(self):
return "Wickets:"+self.wicket+"Runs:"+self.run
class Aauction(Ipl, Carrier):
def __init__(self,wicket,run,name,country,team):
Ipl.__init__(self,name,country,team)
Carrier.__init__(self,wicket,run)
self.Innings=Innings
def stati(self):
return self.info_ipl()+","+self.disp()+"Total Innings:"
x = Aauction(150,2000,"Suresh_Raina","India","kkr")
print(x.stati())
Above code giving following Error:-
Suresh Raina:India
Ipl team:csk
Traceback (most recent call last):
File "C:\Users\Rahul\Desktop\PYTHON\EXP8.py", line 49, in <module>
x = Aauction(150,2000,"Suresh_Raina","India","kkr")
File "C:\Users\Rahul\Desktop\PYTHON\EXP8.py", line 40, in __init__
Carrier.__init__(self,wicket,run)
TypeError: object.__init__() takes no parameters
Thank you.
I think the problem is that your __init__ has three underscores instead of two:
class Carrier:
def ___init__(self,wicket,run):
self.wicket=wicket
self.run=run
def disp(self):
return "Wickets:"+self.wicket+"Runs:"+self.run
should be:
class Carrier:
def __init__(self,wicket,run):
self.wicket=wicket
self.run=run
def disp(self):
return "Wickets:"+self.wicket+"Runs:"+self.run
class myClass:
def __init__(self, text):
self.text = text
def printText(text):
more_text = "Why so "
return more_text + text
Above is a over-simplified version of a code that I am constructing to extract data out of webpages. I am running the temp.py code like this.
>>> from temp import myClass
>>> text = "serious?"
>>> joker_says = myClass(text)
>>>
>>> print joker_says.printText()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "temp.py", line 9, in printText
return more_text + text
TypeError: cannot concatenate 'str' and 'instance' objects
I have seen many examples of concatenation issues of 'str' and 'instance' objects in Stack Overflow.
I have tried the following ways:
OPTION 1: CONVERT text TO STRING DURING init AS INPUT
class myClass:
def __init__(self, str(text)):
self.text = text
def printText(text):
more_text = "Why so "
return more_text + text
But I get ...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "temp.py", line 3
def __init__(self, str(text)):
^
SyntaxError: invalid syntax
== == == == == ==
OPTION 2: CONVERT text TO STRING DURING init STEP
class myClass:
def __init__(self, text):
self.text = str(text)
def printText(text):
more_text = "Why so "
return more_text + text
But I get...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "temp.py", line 9, in printText
return more_text + text
TypeError: cannot concatenate 'str' and 'instance' objects
Can someone please give me a good solution to the problem? Please note that in my original code, my intention is to concatenate two string objects inside the class to create a webpage link. Any suggestion would be appreciated.
You have a couple issues here:
On every function you create for an object, self must be included as the first parameter.
Using your second example:
class myClass:
def __init__(self, text):
self.text = str(text)
def printText(self, text):
more_text = "Why so "
return more_text + text
Then, you make an instance of your class, and you can access the function printText :
joker = myClass("This is some text")
print(joker.text) # This prints: "This is some text"
print(joker.printText("serious?")) # This prints "Why so serious?"
If you want to use that same text as the initializing text, you need to reference it, instead of as a new parameter text, as an attribute of the class, as so:
class myClass:
def __init__(self, text):
self.text = str(text)
def printText(self):
more_text = "Why so "
return more_text + self.text
Then, if you want to reference the above:
joker = myClass("serious?")
print(joker.text) # This prints: "serious?"
print(joker.printText()) # This prints "Why so serious?"
The main problem you are facing is this:
def printText(text):
The reason why you are getting this error is because, as an instance method, the declaration expects you to have self (the instance object) passed as first argument. You are now passing text which is being used as self (the instance). This is why you get the error, because ultimately what you are actually doing is trying to add a string with an instance.
So, knowing that the first argument being passed implicitly to printText is the instance, and looking inside your method, you are actually wanting to reference the self.text inside your printText method. However, your instance being passed in to printText is actually referred to as text. This can be very confusing.
So, following the suggested nomenclature, you should be naming your instance argument as the "expected", self.
With this in mind, your text that you want to reference, can now be referenced as self.text.
This can be shown by fixing your code:
def printText(self):
more_text = "Why so "
return more_text + self.text
I have a class which instances shall be presented as string if being used in the context of a string. To be precise, a attribute pointing to a string should be returned.
The class looks as the following and works so far:
class Test:
string = ""
def __init__(self, value=""):
self.string = value
def __repr__(self):
return str(self.string)
def __str__(self):
return self.__repr__()
def __add__(self, other):
return "%s%s" % (self.string, other)
def __radd__(self, other):
return "%s%s" % (other, self.string)
Unfortunately, I get a TypeError when I try doing something like this:
>>> "-".join([Test("test"), Test("test2")])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, instance found
Doing the same with a string, I get the expected result:
>>> "-".join(["test", "test"])
'test-test'
>>>
I'm pretty sure I'm just missing the correct operator overload function.
Could somebody how to achieve this with class instances in the list?
Thanks.
join requires elements to be strings, as documented here:
https://docs.python.org/3/library/stdtypes.html#str.join
You need to explicitly convert your objects to strings, e.g.:
"-".join(map(str, [Test("test"), Test("test2")]))
The following is my code. Given any content, it has to append certain HTML tag to the content at the front.
I'm learning to write decorators using call instead of function closures.
class decorate:
def __init__(self, tag=""):
self.tag = tag
def __call__(self, function, *args):
return "<p>{}</p>".format(self.tag, function(*args), self.tag)
#decorate(tag="p")
def get_content(content):
return content
print(get_content("I'm awesome"))
# Error i got.
Traceback (most recent call last):
File "cache.py", line 27, in <module>
#decorate(tag="p")
File "cache.py", line 25, in __call__
return "<p>{}</p>".format(self.tag, function(*args), self.tag)
TypeError: get_content() takes exactly 1 argument (0 given)
Change:
def __call__(self, function, *args):
return "<p>{}</p>".format(self.tag, function(*args), self.tag)
into:
def __call__(self, function):
def wrap(*args):
return "<{}>{}</{}>".format(self.tag, function(*args), self.tag)
return wrap
You may want to look into functools for more refined decoration of wrap, but except for supporting help and the like, this should work.
I have a class A with method do_something(self,a,b,c) and another instance method that validates the input and check permissions named can_do_something(self,a,b,c).
This is a common pattern in my code and I want to write a decorator that accepts a validation function name and perform the test.
def validate_input(validation_fn_name):
def validation_decorator(func):
def validate_input_action(self,*args):
error = getattr(self,validation_fn_name)(*args)
if not error == True:
raise error
else:
return func(*args)
return validate_input_action
return validation_decorator
Invoking the functions as follows
#validate_input('can_do_something')
def do_something(self,a,b,c):
return a + b + c
Problem is that i'm not sure how to maintain self through out the validation function. I've used the validation fn name with getattr so the fn could be ran in the context of the instance but i cannot do that for func(*args).
So what is the proper way to achieve this ?
Thanks.
EDIT
So following #André Laszlo answer I realized that self is just the first argument so there is no need to use getattr at all but just pass on the *args.
def validate_input(validation_fn):
def validation_decorator(func):
def validate_input_action(*args):
error = validation_fn(*args)
if not error == True:
raise error
else:
return func(*args)
return validate_input_action
return validation_decorator
Much more elegant and it also supports static methods as well.
Adding a static method to #André Laszlo example proves the decorator is working :
class Foo(object):
#staticmethod
def validate_baz(a,b,c):
if a > b:
return ValueError('a gt b')
#staticmethod
#validate_input(Foo.validate_baz)
def baz(a,b,c):
print a,b,c
>>> Foo.baz(1,2,3)
1 2 3
>>> Foo.baz(2,1,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in validate_input_action
ValueError: a gt b
But, when i'm trying to do them same thing in a django model:
from django.db import models
from django.conf import settings
settings.configure()
class Dummy(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=10)
def can_say_name(self):
if name is None:
return Exception('Does not have a name')
#validate_input(can_say_name)
def say_name(self):
print self.name
#staticmethod
def can_create_dummy(name):
if name == 'noname':
return Exception('No name is not a name !')
#staticmethod
#validate_input(Dummy.can_create_dummy)
def create_dummy(name):
return Dummy.objects.create(name=name)
I get the following :
NameError: name 'Dummy' is not defined
So what is the different between a django model and an Object in relation to this issue ?
I think this does what you want:
def validate_input(validation_fn_name):
def validation_decorator(func):
def validate_input_action(self, *args):
error = getattr(self, validation_fn_name)(*args)
if error is not None:
raise error
else:
arglist = [self] + list(args)
return func(*arglist)
return validate_input_action
return validation_decorator
class Foo(object):
def validate_length(self, arg1):
if len(arg1) < 3:
return ValueError('%r is too short' % arg1)
#validate_input('validate_length')
def bar(self, arg1):
print "Arg1 is %r" % arg1
if __name__ == "__main__":
f = Foo()
f.bar('hello')
f.bar('')
Output is:
Arg1 is 'hello'
Traceback (most recent call last):
File "validator.py", line 27, in <module>
f.bar('')
File "validator.py", line 6, in validate_input_action
raise error
ValueError: '' is too short
Updated answer
The error (NameError: name 'Dummy' is not defined) occurs because the Dummy class is not defined yet when the validate_input decorator gets Dummy as an argument. I guess this could have been implemented differently, but for now that's the way Python works. The easiest solution that I see is to stick to using getattr, which will work because it looks up the method at run time.