object inheritance arugment input error - python-2.7

Playing around with inheritance and came across an error stating that I am inputing too many arguments. What could I be doing wrong?
This first file is called media.py
class Video():
def __init__(self, title, duration):
self.title = title
self.duration = duration
class Movie(Video):
def __init__(self, movie_story, movie_poster, trailer_youtube):
Video.__init__(self, title, duration)
self.storyline = movie_story
self.poster_image_url = movie_poster
self.trailer_youtube_url = trailer_youtube
def show_trailer(self):
webbrowser.open(self.trailer_youtube_url)
class TvShow(Video):
def __init__(self, season, episode, tv_station):
Video.__init__(self, title, duration)
self.season = season
self.episode = episode
self.tv_station = tv_station
This second file creates the objects.
import fresh_tomatoes
import media
family_guy = media.TvShow("Family Guy",
"2000-Present",
"Fifteen Seasons",
"Twenty-Eight",
"Fox")
print family_guy.title
The terminal output states I'm passing 6 arguments when only 4 may be accepted. Why is that?

Calling the parent __init__ will only invoke it , but you still need to pass in the arguments to it.
So when you invoke __init__ method for TvShow it only expects 3 +1(self) arguments , while you were trying to send more than that. So to solve the issue you just need to increase the number of arguments excepted by the __init__.
class Video():
def __init__(self, title, duration):
self.title = title
self.duration = duration
class Movie(Video):
def __init__(self, movie_story, movie_poster, trailer_youtube):
Video.__init__(self, title, duration)
self.storyline = movie_story
self.poster_image_url = movie_poster
self.trailer_youtube_url = trailer_youtube
def show_trailer(self):
webbrowser.open(self.trailer_youtube_url)
class TvShow(Video):
def __init__(self, season, episode, tv_station, title, duration):
Video.__init__(self, title, duration)
self.season = season
self.episode = episode
self.tv_station = tv_station

Related

Python - Overriding a parent variable with a getter/setter

So I have a parent class BaseAdd that I'm trying to subclass. The BaseAdd uses self.left and self.right, I want to use self.nodes to make it easier to access both left and right at once:
class BaseAdd():
def __init__(self, leftright):
self.left = leftright[0]
self.right = leftright[1]
class Add(BaseAdd):
def __init__(self, leftright):
self.nodes = leftright
#property
def left(self):
return self.nodes[0]
#left.setter
def left(self, value):
self.nodes[0] = value
foo = Add(('L', 'R'))
foo.left = "new"
print(foo.left, foo.nodes[0])
>>> ('new', 'L')
The problem is that the setter is never getting called, my hunch is that it's using the BaseAdd.left somehow instead. How can I make the setter properly set the list element?

Replacement for django `render_options`

So I am implementing this answer: Country/State/City dropdown menus inside the Django admin inline, but the def render piece of code needs to be redone.... I have managed to redo it, but I am struggling to find a replacement (or the correct code) for the self.render_options method (which was deprecated on 1.11) of the Widget class.
I am on Django 2.1.
What should I change?
Here is my code:
class StateChoiceWidget(widgets.Select):
def render(self, name, value, attrs=None, renderer=None):
self.choices = [(u"", u"---------")]
if value is None:
value = ''
model_obj = self.form_instance.instance
if model_obj and model_obj.country:
for m in model_obj.country.state_set.all():
self.choices.append((m.id, smart_text(m)))
else:
obj = State.objects.get(id=value)
for m in State.objects.filter(country=obj.country):
self.choices.append((m.id, smart_text(m)))
final_attrs = self.build_attrs(attrs)
output = ['<select%s>' % flatatt(final_attrs)]
for option in self.choices:
output.append('<option value="%s">%s</option>' % (option[0], option[1]))
output.append('</select>')
return mark_safe(''.join(output))
Original poster updated the sample code, so now it doesn't show the code in the question: see previous revision https://stackoverflow.com/revisions/52174508/1
So I figured out the answer. Will post it here in case someone runs into the same issue.
class StateChoiceWidget(widgets.Select):
def render(self, name, value, attrs=None, renderer=None):
self.choices = [(u"", u"---------")]
if value is None or value == '':
value = ''
model_obj = self.form_instance.instance
if model_obj and model_obj.country:
for m in model_obj.country.state_set.all():
self.choices.append((m.id, smart_text(m)))
else:
obj = State.objects.get(id=value)
for m in State.objects.filter(country=obj.country):
self.choices.append((m.id, smart_text(m)))
final_attrs = self.build_attrs(attrs)
s = widgets.Select(choices=self.choices)
select_html = s.render(name=name,value=value,attrs=attrs)
return mark_safe(''.join(select_html))

Passing constructor parameter to a function that generates default value fails

I am very new to Python so I assume I am doing something terribly wrong, but I don't see what and Google has not helped this far too. What is wrong with this ?
def lookup_permille(name):
# TODO: implement a permille lookup table
return 0
def lookup_known_product(name):
# TODO: implement a known product lookup table
return 0
class ProductEntry:
def __init__(self, source, name, price, volume, permille = lookup_permille(name), known_product_id = lookup_known_product(name), category = 0):
self.source = source
self.name = name
self.price = price
self.volume = volume
self.permille = permille
self.price_per_permille = self.permille / self.price;
self.category = category
self.known_product_id = known_product_id
Calling the constructor of ProductEntry fails with:
def __init__(self, source, name, price, volume, permille = lookup_permille(name), known_product_id = lookup_known_product(name), category = 0):
NameError: name 'name' is not defined
The expressions defining default arguments are evaluated when the function is defined, not when it is called. At the point when __init__ is being defined, name does not exist, so it cannot be used in an expression to calculate a default argument.
The usual way to do something like this is to have a stand-in value as your default argument, and replace it with whatever value you actually want inside the body of your function.
def __init__(self, source, name, price, volume,
permille=None, known_product_id=None, category=0):
if permille is None:
permille = lookup_permille(name)
if known_product_id is None:
known_product_id = lookup_known_product(name)
...

Class and Object error; incorrect syntax

How would I be able to print each product? i.e, "I am a iPad, an Apple Product"
class Apple:
def method1(self):
print "I am a %s , an Apple Product" % self
iPad = Apple()
print ipad.method1()
iWatch = Apple()
print iwatch.method1()
iMac = Apple()
print iMac.method1()
class Apple(object):
def __init__(self, name):
self.name = name
def method1(self):
print "I am a %s , an Apple product." % self.name
iPad = Apple('Ipad')
iPad.method1()
iMac = Apple('iMac')
iMac.method1()
iWatch = Apple('iWatch')
iWatch.method1()
This creates 3 instances of the class Apple namely iPad, iWatch and iMac. The init() method is called as soon as those 3 instances are created/instantiated. The string getting passed in then line where each object is instantiated, is the name that will be stored in self.name for each object. 'Self' is just a place holder for the name of the object.
It seems like you want each instance to have its own name that you can print. Something like this (I have named your method1 "describe"):
class Apple(object):
def __init__(self, name):
self.name = name
def describe(self):
return "I am an %s, an Apple Product" % self.name
iPad = Apple("iPad")
print iPad.describe()
iWatch = Apple("iWatch")
print iWatch.describe()
iMac = Apple("iMac")
print iMac.desc()
The self parameter here denotes the object that calls the function. For your purpose, use:
class Apple:
def method1(self,name):
print "I am a %s , an Apple Product" %(name)
iWatch = Apple()
iWatch.method1("iPod")
Or another way of doing it is:
class Apple:
def __init__(self,name):
self.name = name
def method1(self):
print "I am a %s , an Apple Product" %(self.name)
iWatch = Apple("iPod")
iWatch.method1()
Now, this will work.
This is actually a basic fact in Python Classes. Any method of a class takes atleast one parameter, which will be the first parameter in case of multiple parameters to the method, which is the object that calls the function.

I don't know how to interact between classes

If I have this two classes:
class bandido:
def __init__(self, vida, ataque):
self.vida = random.randint(40,81)
self.ataque = random.randint(15,46)
class xiaoling:
def __init__(self, vida, ataque):
self.vida = 100
self.ataque = 100
How can I make a fight? and see who wins?