text: # -*- coding: utf-8 -*-
  """
  DO NOT EDIT THIS FILE WITHOUT CONSULTING WITH ME
  
  @revision: 0 + inputs + Problem
  @author: etodorov
  @date: 14 Feb 16
  
  @revision: 1 + Solver
  @author: etodorov
  @date: 14 Feb 16
  
  @revision: 2 + TestProblem
  @author: etodorov
  @date: 15 Feb 16
  """
  
  from __future__ import division
  import os
  #inputs that MUST be present
  necessaryInputs = set([  'L',
                           'Lf1',
                           'Lf2',
                           'Lf3',
                           'R',
                           'hf',
                           'dtailz',
                           'dtaily',
                           'dlgy',
                           'ns',
                           'ts',
                           'tf',
                           'tst',
                           'hst',
                           'wst',
                           'Sx',
                           'W',
                           'gtd',
                           'dz',
                           'q',
                           'p'])
  
  
  class Problem:
      """
      The wrapper class for all inputs, outputs and communication \n
      Defines inputs that must be present: if any of a set of inputs is missing - raise an error
      \n------------------------------\n
      **Default example** (uses input.csv): \n \t
          >>> Boeing777 = Problem()
      **Change input filename example**: \n \t 
          >>> Boeing777 = Problem("Boeing777_input.csv")
      **Change input parameters example**: \n \t 
          >>> Boeing777 = Problem("Boeing777_input.csv", inputs=["R","L","ts"])
      """
      def __init__(self, fname="input.csv", inputs=necessaryInputs):
          
          self._necessaryInputs = inputs
          self._read_input(fname)
          self.check_attr()
      
      def _read_input(self,fname):
          
          with open("input.csv") as f:
              
              for line in f.readlines():
                  if line[0] == "#":   #ignore comment lines
                      continue
                  cells = line.split(",")
                  try:
                      if cells[2] == "[int]":
                          setattr(self,cells[0], int(cells[1]))
                      elif cells[2] == "mm":
                          setattr(self,cells[0], float(cells[1])/1000.)
                      elif cells[2] == "cm":
                          setattr(self,cells[0], float(cells[1])/100.)
                      elif cells[2] in ["kN", "t"]:
                          setattr(self,cells[0], float(cells[1])*1000.)
                      elif cells[2] in ["m", "N", "kg", "m/s^2"]:
                          setattr(self,cells[0], float(cells[1]))
                      else:
                          print "WARNING:",cells[0], "has a weird unit", cells[2], "please check!"
                          setattr(self,cells[0], float(cells[1]))
                  except ValueError:
                      print "ERROR: Wrong units: ", cells[0]
                      raise ValueError
                  except:
                      print "Unknown Error"
                      raise
                          
      def check_attr(self,necessaryAttrs=[]):
          """        
          Assert that Problem has all neccessary attributes \n
          **Default:** \n \t 
              >>> Boeing777.check_attr() uses Boeing777._necessaryInputs \n
          **Example:** \n \t 
              >>> Boeing777.check_attr("Lf1","Lf2")
          """
          
          if len(necessaryAttrs)==0:
              necessaryAttrs = self._necessaryInputs
          for attr in necessaryAttrs:
              try:
                  getattr(self, attr)
              except AttributeError:
                  raise AttributeError("Some of the necessary inputs are missing: " + attr)
              except:
                  print "UnknownError"
                  raise
                  
                  
  class Solver:
      """
      Base class for the solvers /n
      """
      def __init__(self,inputL,outputL):
          self.inputList = inputL
          self.outputList = outputL
      def check_input(self, problem):
          problem.check_attr(self.inputList)
      def check_output(self,problem):
          problem.check_attr(self.outputList)
      
  class TestProblem():
      pass
  