Class and Object error; incorrect syntax - python-2.7

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.

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?

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)
...

object inheritance arugment input error

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

Is it dangerous to define __contains__ on a metaclass?

I'm writing a custom EnumMeta class in Python 2.7 that will collect enum keys and values from some class and augment that class with some additional fields.
class EnumMeta(type):
def __init__(cls, name, bases, props):
cls.__all_values__ = [...] # collect all interesting properties
def __contains__(cls, value):
return value in cls.__all_values__
class TheFellowshipOfTheRing(object):
__metaclass__ = EnumMeta
FRODO = 'Frodo Baggins'
SAM = 'Samwise "Sam" Gamgee'
MERRY = 'Meriadoc "Merry" Brandybuck'
PIPPIN = 'Peregrin "Pippin" Took'
GANDALF = 'Gandalf the Grey'
ARAGORN = 'Aragorn (Strider)'
LEGOLAS = 'Legolas'
GIMLI = 'Gimli'
BOROMIR = 'Boromir'
print 'Gandalf the Grey' in TheFellowshipOfTheRing
# True
print 'Saruman' in TheFellowshipOfTheRing
# False
I'm wondering if implementing container-specific functions, such as __contains__, on a metaclass is a dangerous thing to do, and if so, why?

coercing to Unicode: need string or buffer, NoneType found

I am making an Ajax request into views as follows:
def all_json_models(request):
data = {}
try:
isp = request.GET['status']
present_isp = Priority.objects.filter(ispname = isp)
isp_count = MultiWAN.objects.all()
# data['latest_no_rules'] = latest_no_rules
#data['present_isp'] = present_isp
data['isp_count'] = isp_count
return HttpResponse(simplejson.dumps(data))
my models.py is like
class MultiWAN(models.Model):
isp_name = models.CharField(max_length=10)
description = models.TextField(null=True)
ip_address = models.IPAddressField(null=True)
subnet = models.IPAddressField(null=True)
gateway = models.IPAddressField(null=True)
nameserver = models.ForeignKey('NameServer')
weight = models.IntegerField(null=False)
interface = models.CharField(max_length=5)
def __unicode__(self):
"""
This function is to return the values we required.
Arguments:
- `self`:
"""
# return u'%s ' % (self.isp_name)
class NameServer(models.Model):
""" A Isp can have more than one nameserver so far we are declearing a seperate table
"""
name = models.IPAddressField(null=False)
class Priority(models.Model):
priority = models.IntegerField(null = True)
ispname = models.ForeignKey('MultiWAN')
rule = models.CharField(max_length=5,null=False)
From = models.IPAddressField(null=True)
To = models.IPAddressField(null=True)
def __unicode__(self):
return u'%s ' % (self.priority)
while making request i am getting the error:
"coercing to Unicode: need string or buffer, NoneType found"
What i am doing wrong here?
It's hard to tell without the full traceback (because it gives information about where in you code the exception is thrown).
The error message "coercing to Unicode: need string or buffer, NoneType found" means that, at some point, django tried to convert something to unicode and expected a string, but received None. This means that either you call a function passing None instead of a string, or one of you methods returns None instead of a string.
In the code you showed us, MultiWAN.__unicode__ seems ill-defined. Maybe the error stems from this ?