Solved

Calling a python method from a class

Posted on 2010-08-20
11
794 Views
Last Modified: 2012-05-10
I've tried reading the python docs on classes, objects and data models but I still don't get it - I suppose that advanced programmers need to write classes but for what I'm able to do, writing a class seems to make things more difficult than they need to be.

I'm trying to write a program that requires me to create an instance of a 'Dog' class with the dog's name and breed as arguments, and append the object to the dogs list. For each user input on the name and breed, the current dogs list should print the name and breed of each dog, example:
#DOGS
0. Snoopy:Beagle
1. Marmaduke:Great Dane
2. Rover:Mutt

I can't figure out how to call the function so I'm not sure if the problem is with the way I'm trying to call the function or the way that I've written the methods in the class. Some of the guidance was fairly specific, for example the init() method should take two parameters, name and breed, in addition to the implicit self.  

I've copied the errors below with the offending code, and I don't understand the errors (if I did, I suppose I could fix this).

class Dog:

    def __init__(self, name, breed):
        self.name = 'Dog Name'
        self.breed = 'Dog Breed'
        self.dog_list = []

    # because 'dogs' in add_dog(**dogs) turned out to be undefined,  
    # not sure why...
    def keywords_as_dict(**dogs):
        return dogs
       
    def add_dog(**dogs):
	while True:
            try:
                name = raw_input("Enter dog name: ")
                breed = raw_input("Enter dog breed: ")

    		for name, breed in dogs.items():
            	    my_dog = (name.capitalize() + ": " + breed.capitalize())
                    print(my_dog)
                    dog_list.append(my_dog)
	    
	    except name == '':
                print('Exiting program')

        return dogs, dog_list
                           
if __name__ == "__main__":
    zero = Dog(name='Lassie', breed='Retriever') # or 
    one = Dog('Lassie', 'Retriever')
    print(zero, one) 
    # prints <__main__.Dog instance at some hex code> for each
    Dog.add_dog(one) # type error, method takes 0 args 
    Dog.add_dog() # or
    Dog.add_dog('Goofy', 'mutt') # or 
    Dog.add_dog(name='Goofy', breed='mutt') # type errors,
    # unbound methods must be called with class instance as first argument

Open in new window

0
Comment
Question by:sara_bellum
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
11 Comments
 
LVL 41

Assisted Solution

by:HonorGod
HonorGod earned 500 total points
ID: 33489952
To start with, part of your problem is related to trying to have the "list" the way you do.

Let's start simply, and just define a class Dog that has a constructor which saves the dogs name and breed.
>>> class Dog :
...   def __init__( self, name, breed ) :
...     self.name = name;
...     self.breed = breed;
...
>>> lassie = Dog( 'Lassie', 'collie' )
>>>
>>> print lassie.name
Lassie
>>> print lassie.breed
collie
>>>

Open in new window

0
 
LVL 41

Assisted Solution

by:HonorGod
HonorGod earned 500 total points
ID: 33489974
We could use this class to save information about individual dogs. but we really should have a "getter" to access the instance attributes;

Maybe something like:

----------
>>> execfile( 'dog.py' )
>>> a = Dog( 'Bubba', 'mixed' )
>>> print a.getName()
Bubba
>>> print a.getBreed()
mixed
>>>
>>> kennel = [ a, Dog( 'Li', 'Pug' ) ]
>>> for dog in kennel :
...   print dog.getName(), dog.getBreed()
...
Bubba mixed
Li Pug
>>>

class Dog() :
   def __init__( self, name, breed ) :
     self.name = name;
     self.breed = breed;
   def getName( self ) :
     return self.name;
   def getBreed( self ) :
     return self.breed;

Open in new window

0
 
LVL 41

Assisted Solution

by:HonorGod
HonorGod earned 500 total points
ID: 33489983
Oh, using your examples:


>>> execfile( 'dog.py' )
>>> kennel = [ Dog( 'Snoopy' ,'Beagle' ), Dog( 'Marmaduke', 'Great Dane' ), Dog( 'Rover', 'Mutt' ) ]
>>> for i in range( len( kennel ) ) :
...   print '%d. %s:%s' % ( i, kennel[ i ].getName(), kennel[ i ].getBreed() );
...
0. Snoopy:Beagle
1. Marmaduke:Great Dane
2. Rover:Mutt
>>>

Open in new window

0
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 
LVL 13

Expert Comment

by:Superdave
ID: 33490181
Some problems with what you've got:
__init__ doesn't do anything with its arguments
add_dog doesn't do anything with the input it asks for
The methods keywords_as_dict and add_dog should both have self as the first argument.
Line 30: the Dog constructor takes two arguments (name and breed).
Lines 34-37: Dog is a class, not an instance.
0
 
LVL 13

Expert Comment

by:Superdave
ID: 33490322
Here's a fixed-up version of what I think you were trying to do
class Dog:

    def __init__(self, name, breed):
        self.name = 'Dog Name'
        self.breed = 'Dog Breed'
        self.dog_list = []

    # because 'dogs' in add_dog(**dogs) turned out to be undefined,  
    # not sure why...
    def keywords_as_dict(**dogs):
        return dogs
       
    def add_dog(**dogs):
	while True:
            try:
                name = raw_input("Enter dog name: ")
                breed = raw_input("Enter dog breed: ")

    		for name, breed in dogs.items():
            	    my_dog = (name.capitalize() + ": " + breed.capitalize())
                    print(my_dog)
                    dog_list.append(my_dog)
	    
	    except name == '':
                print('Exiting program')

        return dogs, dog_list
                           
if __name__ == "__main__":
    zero = Dog(name='Lassie', breed='Retriever') # or 
    one = Dog('Lassie', 'Retriever')
    print(zero, one) 
    # prints <__main__.Dog instance at some hex code> for each
    Dog.add_dog(one) # type error, method takes 0 args 
    Dog.add_dog() # or
    Dog.add_dog('Goofy', 'mutt') # or 
    Dog.add_dog(name='Goofy', breed='mutt') # type errors,
    # unbound methods must be called with class instance as first argument

Open in new window

0
 

Author Comment

by:sara_bellum
ID: 33490714
I think I understand HonorGod's code, thanks very much!

But I can get the required output with the code below - I'm still very confused about how to construct a class to do the same thing. I'll have to think about that some more, it's late and another long day tomorrow.
if __name__ == "__main__":
    
    kennel = []
    while True:
        name = raw_input("Name: ")
        if name != '':
            breed = raw_input("Breed: ")
            my_dog = (name.capitalize() + ": " + breed.capitalize())
            kennel.append(my_dog)
            print('DOGS')
            for i,  my_dog in enumerate( kennel ):
                print str(i) + '.',  my_dog
            print('*' * 20) 
        else:
            print('*' * 20)
            sys.exit()

Open in new window

0
 
LVL 41

Accepted Solution

by:
HonorGod earned 500 total points
ID: 33491644
Line 8 doesn't create a "Dog"

instead of:

my_dog = (name.capitalize() + ": " + breed.capitalize())

You need something like:

my_dog = Dog( name.capitalize(), breed.capitalize() );

How about something like:
class Dog() :
  def __init__( self, name, breed ) :
    self.name = name;
    self.breed = breed;
  def getName( self ) :
    return self.name;
  def getBreed( self ) :
    return self.breed;

if __name__ == '__main__' :
  kennel = [];             # Create an empty list of dogs
  while True :
    name = raw_input( ' Name: ' ).strip();
    if name :
      breed = raw_input( 'Breed: ' ).strip();
      if breed :
        kennel.append( Dog( name.capitalize(), breed.capitalize() ) );
    else :
      break;
  print '\nDogs:\n' + ( '-' * 40 );
  for i in range( len( kennel ) ) :
    dog = kennel[ i ];
    print '%d. %s:%s' % ( i, dog.getName(), dog.getBreed() );

else :
  print "Error - execute this script, don't import it.\n";
  print 'python %s.py' % __name__;

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
ID: 33491647
Sample output:


C:\>python dog.py
 Name: Snoopy
Breed: Beagle
 Name: Marmaduke
Breed: Great Dane
 Name: Rover
Breed: Mutt
 Name:

Dogs:
----------------------------------------
0. Snoopy:Beagle
1. Marmaduke:Great dane
2. Rover:Mutt

Open in new window

0
 
LVL 13

Expert Comment

by:Superdave
ID: 33491668
The class won't do much with such a simple example.  In HonorGod's example the class takes the place of a tuple of (name,breed) and doesn't do much more than a tuple would, except arguably make it more understandable because you access the elements by name GetName and GetBreed instead of [0] and [1].  In the example I modified from yours, the object takes the place of a list, and again doesn't really provide any more functionality, except you can add to it using named keywords instead of a tuple so it's maybe more understandable.  You could make an example that uses two classes, one for the list and one for the tuple, if you really wanted to demonstrate objects.
0
 

Author Closing Comment

by:sara_bellum
ID: 33494075
Thanks - I appreciate your trying to take me through this one step at a time but in the end I just couldn't connect the dots...I'll get used to this, I'm sure of it :)
0
 
LVL 41

Expert Comment

by:HonorGod
ID: 33495136
Thanks for the grade & points

Good luck & have a great day.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Flask is a microframework for Python based on Werkzeug and Jinja 2. This requires you to have a good understanding of Python 2.7. Lets install Flask! To install Flask you can use a python repository for libraries tool called pip. Download this f…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

622 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question