Python: convert script from procedural to OOP style
Question: I wrote this simple Munin plugin to graph average fan speed and I want to redo
it to OOP - strictly as a learning exercise. Don't have a clue where to start
though. Anyone feel like offering some guidance or even an example of what
this script should look like when done. I will use it to redo some other
scripts into an OOP style as well; again for learning purposes.

    
    
    import sys
    import subprocess
    
    CMD = "/usr/sbin/omreport chassis fans".split()
    
    # Munin populates sys.argv[1] with "" (an empty argument), lets remove it.
    sys.argv = [x for x in sys.argv if x]
    
    if len(sys.argv) > 1:
        if sys.argv[1].lower() == "autoconfig":
            print "autoconfig"
        elif sys.argv[1].lower() == "config":
            print "graph_title Average Fan Speed"
            print "graph_args --base 1000 -l 0"
            print "graph_vlabel speed (RPM)"
            print "graph_category Chassis"
            print "graph_info This graph shows the average speed of all fans"
            print "graph_period second"
            print "speed.label speed"
            print "speed.info Average fan speed for the five minutes."
    else:
        try:
            data = subprocess.Popen(CMD,stdout=subprocess.PIPE).stdout.readlines()
        except OSError, e:
            print >> sys.stderr, "Error running '%s', %s" % (" ".join(cmd), e)
            sys.exit(1)
    
        count = total = 0
        for item in data:
            if "Reading" in item:
                # Extract variable length fan speed, without regex.
                total += int(item.split(":")[1].split()[0])
                count += 1
        # Sometimes omreport returns zero output if omsa services aren't started.
        if not count or not total:
            print >> sys.stderr, 'Error: "omreport chassis fans" returned 0 output.'
            print >> sys.stderr, 'OMSA running? Try: "srvadmin-services.sh status".'
            sys.exit(1)
    
        avg = (total / count)
        print "speed.value %s" % avg
    


Answer: You remake it in OOP by identifying code and data that goes together. These
you then merge into "classes".

You actual data above seems to be the output of a process. The code is
iterating over it. I guess you can make a class out of that if you want to,
but it's a bit silly. :)

So, something like this (obviously completely untested code):

    
    
    import sys
    import subprocess
    
    class Fanspeed(object):
    
        def __init__(self, command):
            self.command = command.split()
    
        def average_fan_speed(self):
            data = subprocess.Popen(CMD,stdout=subprocess.PIPE).stdout.readlines()
    
            count = total = 0
            for item in data:
                if "Reading" in item:
                    # Extract variable length fan speed, without regex.
                    total += int(item.split(":")[1].split()[0])
                    count += 1
            # Sometimes omreport returns zero output if omsa services aren't started.
            if not count or not total:
                raise ValueError("I found no fans. Is OMSA services started?"
    
            avg = (total / count)
            return % avg
    
    if __main__ == '__main__':
        # Munin populates sys.argv[1] with "" (an empty argument), lets remove it.
        sys.argv = [x for x in sys.argv if x]
    
        if len(sys.argv) > 1:
            if sys.argv[1].lower() == "autoconfig":
                print "autoconfig"
            elif sys.argv[1].lower() == "config":
                print "graph_title Average Fan Speed"
                print "graph_args --base 1000 -l 0"
                print "graph_vlabel speed (RPM)"
                print "graph_category Chassis"
                print "graph_info This graph shows the average speed of all fans"
                print "graph_period second"
                print "speed.label speed"
                print "speed.info Average fan speed for the five minutes."
        else:
            try:
                cmd = "/usr/sbin/omreport chassis fans"
                fanspeed = Fanspeed(cmd)
                average = fanspeed.average_fan_speed()
            except OSError, e:
                print >> sys.stderr, "Error running '%s', %s" % (cmd, e)
                sys.exit(1)
            except ValueError, e:
                # Sometimes omreport returns zero output if omsa services aren't started.
                print >> sys.stderr, 'Error: "omreport chassis fans" returned 0 output.'
                print >> sys.stderr, 'OMSA running? Try: "srvadmin-services.sh status".'
                sys.exit(1)
    

But YMMV. It's perhaps a bit clearer.

