Solved

Calling a python method from a class

Posted on 2010-08-20
11
783 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
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!

 
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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering 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

Suggested Solutions

Title # Comments Views Activity
groupSumClump challenge 9 139
Excel file not created as expected 7 94
Advice in Xamarin 21 109
Problem to picture file 20 69
A set of related code is known to be a Module, it helps us to organize our code logically which is much easier for us to understand and use it. Module is an object with arbitrarily named attributes which can be used in binding and referencing. …
Introduction On September 29, 2012, the Python 3.3.0 was released; nothing extremely unexpected,  yet another, better version of Python. But, if you work in Microsoft Windows, you should notice that the Python Launcher for Windows was introduced wi…
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
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.

730 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