Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Calling a python method from a class

Posted on 2010-08-20
11
Medium Priority
?
799 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 2000 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 2000 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 2000 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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 2000 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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

721 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