Python Sample

Code sample

# TEST PROGRAM
"""Program level documentation.

This is a test program that groups the key features and principle for maintainability
1.- logging
2.- exception handling
3.- single point of entry
4.- argument -v -h
5.- clean architecture (separation of level)
"""

import time
import platform
import sys, getopt
import logging

from pi_controllerlib import *
from pi_spinnerlib import *
from pi_emoji import EMOJI_UNICODE

def show_off():
   print(" ")

   print("               $$ $$$$$ $$ ")
   print("               $$ $$$$$ $$ ")
   print("              .$$ $$$$$ $$. ")
   print("              :$$ $$$$$ $$: ")
   print("              $$$ $$$$$ $$$ ")
   print("              $$$ $$$$$ $$$ ")
   print("             ,$$$ $$$$$ $$$. ")
   print("            ,$$$$ $$$$$ $$$$. ")
   print("           ,$$$$; $$$$$ :$$$$. ")
   print("          ,$$$$$  $$$$$  $$$$$. ")
   print("        ,$$$$$$'  $$$$$  `$$$$$$. ")
   print("      ,$$$$$$$'   $$$$$   `$$$$$$$. ")
   print("   ,s$$$$$$$'     $$$$$     `$$$$$$$s. ")
   print(" $$$$$$$$$'       $$$$$       `$$$$$$$$$ ")
   print(" $$$$$Y'          $$$$$          `Y$$$$$ ")

   print(" ")

def spinning_cursor():
    while True:
        for cursor in '|/-\\':
            yield cursor

def spinning(rangedef):
   spinner = spinning_cursor()
   for _ in range(rangedef):
      sys.stdout.write(next(spinner))
      sys.stdout.flush()
      time.sleep(0.1)
      sys.stdout.write('\b')

def main(argv):
   """ Main entry point

   This is the main entry point for the system call.
   This will manage the arguments
   """

   print("------------------------------------------------")
   print EMOJI_UNICODE[u':beer_mug:']
   #print u'\U0001F1E8\U0001F1F5'
   #show_off()
   #print("------------------------------------------------")

   service_start = time.time()
   service_status = True
   service_name = "Test Service"

   arg_duration = 0.1
   arg_nbr = 10

   # Argument Check
   try:
      opts, args = getopt.getopt(argv,"vhi:o:",["ifile=","ofile="])
   except getopt.GetoptError:
      print 'test.py -i <duration> -o <nbr>'
      sys.exit(2)

   # Argument loop
   for opt, arg in opts:
      if opt == '-h':
         print ' Usage: test.py -i <duration> -o <nbr>'
         print '   -h help'
         print '   -v version'
         sys.exit()
      elif opt == '-v':
         print 'test 1.0.001 '
         sys.exit()
      elif opt in ("-i", "--ifile"):
         arg_duration = arg
      elif opt in ("-o", "--ofile"):
         arg_nbr = arg

   controllerClass = ControllerClass(float(arg_duration), int(arg_nbr))

   try:
      print("Configuration Check")
      spinner = Spinner()
      spinner.start()
      # ... some long-running operations
      # ... with no output.
      time.sleep(3) 
      spinner.stop()

      controllerClass.Check()
      controllerClass.ShowConfig()
      print("Service Start")
      controllerClass.Run()
   except:
      return "N/A"

   print("------------------------------------------------")
   service_end = time.time()
   service_duration =  service_end - service_start
   print("Service duration %.3f seconds" % service_duration)

   print("------------------------------------------------")

if __name__ == "__main__":
   main(sys.argv[1:])

def linux_distribution():
  try:
    return platform.linux_distribution()
  except:
    return "N/A"

Controller library test


import sys
import logging
import logging.config

class ControllerClass:

   CONST_NBR = 12345    # An integer assignment
   CONST_NAME = "Controller Service"
   CONST_VERSION = "1.0.0.0"

   def __init__(self, duration_part, nbr_part):

        # variable initialisation
        self.duration = duration_part           # An integer assignment
        self.nbr = nbr_part                     # An integer assignment

        # create logger
        self.logger = logging.getLogger("ControllerClass")
        self.logger.setLevel(logging.DEBUG)   
        self.ch = logging.StreamHandler()
        self.ch.setLevel(logging.DEBUG)
        self.formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        self.ch.setFormatter(self.formatter)
        self.logger.addHandler(self.ch)

        # Stats
        self.stats = []

   def Check(self):
    self.logger.info("Python version %s" % sys.version)
    self.logger.info("Python version %s" % sys.version_info)

    if sys.version_info<(2,6,0):
        sys.stderr.write("You need python 2.6 or later to run this script\n")
        exit(1)

   def ShowConfig(self):
       self.logger.info("------------------------------------------------")
       self.logger.info("Name      : %s" % self.CONST_NAME)
       self.logger.info("Version   : %s" % self.CONST_VERSION)
       self.logger.info("CONST_NBR : %d" % self.CONST_NBR)
       self.logger.info("Nbr       : %d" % self.nbr)
       self.logger.info("Duration  : %.2f" % self.duration)
       self.logger.info("------------------------------------------------")

   def Run(self):
       self.logger.info("Run ......")

Spinner multipthread


# MULTI THREADED - SPINNER 
"""Multi Threaded Spinner Library

This library is used to make the layout nicer.
not really an advantage :-)

Credit: (Victor Moyseenko) 
https://stackoverflow.com/questions/4995733/how-to-create-a-spinning-command-line-cursor

"""
import sys
import time
import threading

class Spinner:
    busy = False
    delay = 0.1

    @staticmethod
    def spinning_cursor():
        while 1: 
            for cursor in '|/-\\': yield cursor

    def __init__(self, delay=None, text=None):
        self.spinner_generator = self.spinning_cursor()
        if delay and float(delay): self.delay = delay

    def spinner_task(self):
        while self.busy:
            sys.stdout.write(next(self.spinner_generator))
            sys.stdout.flush()
            time.sleep(self.delay)
            sys.stdout.write('\b')
            sys.stdout.flush()

    def start(self):
        self.busy = True
        threading.Thread(target=self.spinner_task).start()

    def stop(self):
        self.busy = False
        time.sleep(self.delay)