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.

Member Avatar for leegeorg07

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']
commented: real nice example code +6
commented: great code +1

Wow vidaj, real classy and generic example of Python class!
Thank you!

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!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.