Hi there,

I've been searching the documentation but I can't find any answers (perhaps I'm asking the wrong questions).

Say we have a list of animals: Sheep, Cow, Pig, Horse.

All of these animals have attributes (4 legs, etc.)

We have the name of the animal and the attributes stored (for now) as a list for each animal.

I would like to create a program that quickly finds how similar two animals are. E.g. "Compare sheep and cow" - from our list of attributes we get 4 legs, 2 eyes, etc.

Of course, I could do simple list comparison. But how else could I organise the data?

I was thinking perhaps of using a hashed database whereby the "animal" key points to the attributes. But how could I go about this in python?

I'm happy to use a MySQL database (I have the MySQldb module) but I'm just not sure how to organise this stuff.

Any help appreciated.

you could use classes an example using shapes is:

class chape:
    def__init__(self, sides, name, sides2, name2):
        self.shape = [sides, name]
        self.shape2 = [sides2, name2]
    def issame(self):
        if name2:
            if self.shape == self.shape2:
                print("they are the same")
            else:
                print("they are not the same")
        else:
            print("you did not specify two shapes")

wich you could use like this:

a = shape(4, 'Rectangle', 4, 'Square')
a.issame()
#outputs 
#they are not the same
a = shape(3, 'triangle', 3, 'triangle')
a.issame()
#outputs
#they are the same

Classes are excellent in this case. That's what they are there for - organizing data :)

Consider using a base class for Animal, and subclass the other animal if you know the value at compiletime. Or use a subklass where you fill inn the attributes at load-time. I included some examples of how it can be done. This is python 3 syntax, so bear with me :)

class Animal(object):
    """
    Base class for all animals
    """
    def __init__(self, **kwargs):
        for attribute, value in kwargs.items():
            setattr(self, attribute, value)
    
    def compare(self, attribute, otherAnimal):
        try :
            myValue = getattr(self, attribute)                # if attribute = tail, this equals myValue = self.tail
            otherValue = getattr(otherAnimal, attribute)      #      -- = --         this equals otherValue = otherAnimal.tail
            
            highObject = self if myValue > otherValue else otherAnimal    # Find the object with the highest value
            lowObject = self if myValue < otherValue else otherAnimal     # Find the object with the lowest value
            
            if myValue == otherValue:         # Values might me equal
                print("{0} and {1} has the same amount of {2}".format(self.getName(), otherAnimal.getName(), attribute)) 
            else:                             # Values are not equal
                print("{0} has more {1} than {2}".format(highObject.getName(), attribute, lowObject.getName()))
        except AttributeError as e:           # This exception is raies if the attribute doesn't exist
            print(e)
    
    
    def equalities(self, otherAnimal):
        return [x for x in self.__dict__ if not x.startswith('__') 
                                            and hasattr(otherAnimal, x) 
                                            and getattr(self, x) == getattr(otherAnimal, x)]
            
    
    def getName(self):
        return self.__class__.__name__   # Default name to class-name

class Cow(Animal):
    def __init__(self):
        self.legs = 4
        self.eyes = 2
        self.tail = 1

class Spider(Animal):
    def __init__(self):
        self.legs = 8
        self.eyes = 8 * 10 ** 7
        
class MysteryAnimal(Animal):
    
    def __init__(self, name, **kwargs):
        super().__init__(**kwargs)       # Call Animal constructor
        self.getName = lambda: name      # Override getName to return this custom name 
    

cow = Cow()
spider = Spider()
dog = MysteryAnimal('Dog', legs=4, eyes=2, tail=1)
cat = MysteryAnimal('Cat', **{'legs':4, 'eyes':2, 'tail':2})

cow.compare('legs', spider)
cow.compare('eyes', spider)
cow.compare('tail', spider)
dog.compare('tail', cat)
print("Cow has a tail? {0}".format(cow.tail))
dog.compare('tail', cow)
print(cow.equalities(cat))

Produces the following output:

Spider has more legs than Cow
Spider has more eyes than Cow
'Spider' object has no attribute 'tail'
Cat has more tail than Dog
Cow has a tail? 1
Dog and Cow has the same amount of tail
['eyes', 'legs']
Comments
great code
real nice example code

Of course, I could do simple list comparison.

However you organize it, you will have to compare all fields, i.e. cow_list[1] == sheep_list[1] = number of legs ==> ctr += 1 A hashed db or MySQL would only improve things if you were looking for all animals with 4 legs as you could look that up. It would not tell how similar 2 animals were. You would still have to compare individual attributes.

Thanks all for your input.. I will give classes a go. Expect some confused future postings!

This article has been dead for over six months. Start a new discussion instead.