signature:
def clone ( self ) :
    """Create a complete copy of self .
 : returns : A MaterialPackage that is identical to self ."""

implementation:
result = copy . copy ( self )
result . size_class_masses = copy . deepcopy ( self . size_class_masses )
return result


signature:
def clear ( self ) :
    """Set all the size class masses and H20 _ mass in the package to zero
 and the solid _ density to 1.0"""

implementation:
self . solid_density = 1.0
self . H2O_mass = 0.0
self . size_class_masses = self . size_class_masses * 0.0


signature:
def create_template ( material , path , show = False ) :
    """Create a template csv file for a data set .
 : param material : the name of the material
 : param path : the path of the directory where the file must be written
 : param show : a boolean indicating whether the created file should be displayed after creation"""

implementation:
file_name = 'dataset-%s.csv' % material . lower ( )
file_path = os . path . join ( path , file_name )
with open ( file_path , 'w' , newline = '' ) as csvfile :
    writer = csv . writer ( csvfile , delimiter = ',' , quotechar = '"' , quoting = csv . QUOTE_MINIMAL )
    writer . writerow ( [ 'Name' , material ] )
    writer . writerow ( [ 'Description' , '<Add a data set description ' 'here.>' ] )
    writer . writerow ( [ 'Reference' , '<Add a reference to the source of ' 'the data set here.>' ] )
    writer . writerow ( [ 'Temperature' , '<parameter 1 name>' , '<parameter 2 name>' , '<parameter 3 name>' ] )
    writer . writerow ( [ 'T' , '<parameter 1 display symbol>' , '<parameter 2 display symbol>' , '<parameter 3 display symbol>' ] )
    writer . writerow ( [ 'K' , '<parameter 1 units>' , '<parameter 2 units>' , '<parameter 3 units>' ] )
    writer . writerow ( [ 'T' , '<parameter 1 symbol>' , '<parameter 2 symbol>' , '<parameter 3 symbol>' ] )
    for i in range ( 10 ) :
        writer . writerow ( [ 100.0 + i * 50 , float ( i ) , 10.0 + i , 100.0 + i ] )
if show is True :
    webbrowser . open_new ( file_path )


signature:
def calculate ( self , ** state ) :
    """Base calculate method for models .
 Validates the material state parameter ( s ) .
 : param * * state : The material state"""

implementation:
if not self . state_validator . validate ( state ) :
    msg = f"{self.material} {self.property} model. The state "
    msg += f"description ({state}) contains errors:"
    for key , value in self . state_validator . errors . items ( ) :
        msg += ' %s: %s;' % ( key , value )
    msg = msg [ 0 : - 1 ] + '.'
    raise ValidationError ( msg )


signature:
def delete ( self , endpoint , data , url_data = None , parameters = None ) :
    """Returns the response and body for a delete request
 endpoints = ' users ' # resource to access
 data = { ' username ' : ' blah , ' password ' : blah } # DELETE body
 url _ data = { } , ( ) # Used to modularize endpoints , see _ _ init _ _
 parameters = { } , ( ( ) , ( ) ) # URL paramters , ex : google . com ? q = a & f = b"""

implementation: return self . request_handler . request ( self . _url ( endpoint , url_data , parameters ) , method = Api . _method [ 'delete' ] , body = urllib . urlencode ( data ) )


signature:
def head ( self , endpoint , url_data = None , parameters = None ) :
    """Returns the response and body for a head request
 endpoints = ' users ' # resource to access
 url _ data = { } , ( ) # Used to modularize endpoints , see _ _ init _ _
 parameters = { } , ( ( ) , ( ) ) # URL paramters , ex : google . com ? q = a & f = b"""

implementation: return self . request_handler . request ( self . _url ( endpoint , url_data , parameters ) , method = Api . _method [ 'head' ] )


signature:
def _url ( self , endpoint , url_data = None , parameters = None ) :
    """Generate URL on the modularized endpoints and url parameters"""

implementation:
try :
    url = '%s/%s' % ( self . base_url , self . endpoints [ endpoint ] )
except KeyError :
    raise EndPointDoesNotExist ( endpoint )
if url_data :
    url = url % url_data
if parameters : # url = url ? key = value & key = value & key = value . . .
    url = '%s?%s' % ( url , urllib . urlencode ( parameters , True ) )
return url


signature:
def _httplib2_init ( username , password ) :
    """Used to instantiate a regular HTTP request object"""

implementation:
obj = httplib2 . Http ( )
if username and password :
    obj . add_credentials ( username , password )
return obj


signature:
def calculate ( self , ** state ) :
    """Calculate dynamic viscosity at the specified temperature and
 composition :
 : param T : [ K ] temperature
 : param x : [ mole fraction ] composition dictionary , e . g . { ' SiO2 ' : 0.25 , ' CaO ' : 0.25 , ' MgO ' : 0.25 , ' FeO ' : 0.25}
 : returns : [ Pa . s ] dynamic viscosity
 The * * state parameter contains the keyword argument ( s ) specified above that are used to describe the state of the material ."""


signature:
def calculate ( self , ** state ) :
    """Calculate dynamic viscosity at the specified temperature and
 composition :
 : param T : [ K ] temperature
 : param y : [ mass fraction ] composition dictionary , e . g . { ' SiO2 ' : 0.25 , ' CaO ' : 0.25 , ' MgO ' : 0.25 , ' FeO ' : 0.25}
 : returns : [ Pa . s ] dynamic viscosity
 The * * state parameter contains the keyword argument ( s ) specified above that are used to describe the state of the material ."""

implementation:
T = state [ 'T' ]
y = state [ 'y' ]
x = amount_fractions ( y )
return super ( ) . calculate ( T = T , x = x )


implementation:
T = state [ 'T' ]
x = state [ 'x' ]
# create the slag constituent categories
compounds_sio2 = [ 'SiO2' , 'PO2.5' , 'TiO2' , 'ZrO2' ]
compounds_cao = [ 'CaO' , 'MgO' , 'FeO1.5' , 'FeO' , 'MnO' , 'BO1.5' ]
compounds_al2o3 = [ 'Al2O3' ]
compounds_caf2 = [ 'CaF2' ]
compounds_na2o = [ 'Na2O' , 'K2O' ]
compounds_all = ( compounds_sio2 + compounds_cao + compounds_al2o3 + compounds_caf2 + compounds_na2o )
# convert compounds with two cations to single cation equivalents
if 'P2O5' in x :
    x [ 'PO2.5' ] = 2.0 * x [ 'P2O5' ]
if 'Fe2O3' in x :
    x [ 'FeO1.5' ] = 2.0 * x [ 'Fe2O3' ]
if 'B2O3' in x :
    x [ 'BO1.5' ] = 2.0 * x [ 'B2O3' ]
# normalise mole fractions , use only compounds in compounds _ all
x_total = sum ( [ x . get ( c , 0.0 ) for c in compounds_all ] )
x = { c : x . get ( c , 0.0 ) / x_total for c in compounds_all }
# calculate the cateogry mole fractions
x1 = sum ( [ x . get ( c , 0.0 ) for c in compounds_sio2 ] )
x2 = sum ( [ x . get ( c , 0.0 ) for c in compounds_cao ] )
x3 = sum ( [ x . get ( c , 0.0 ) for c in compounds_al2o3 ] )
x4 = sum ( [ x . get ( c , 0.0 ) for c in compounds_caf2 ] )
x5 = sum ( [ x . get ( c , 0.0 ) for c in compounds_na2o ] )
# TODO : Why is x1 not used ? This looks suspicious .
A = exp ( - 17.51 + 1.73 * x2 + 5.82 * x4 + 7.02 * x5 - 33.76 * x3 )
B = 31140.0 - 23896.0 * x2 - 46356.0 * x4 - 39159.0 * x5 + 68833.0 * x3
result = A * T * exp ( B / T )
return result / 10.0


signature:
def alpha ( self , ** state ) :
    """Calculate the alpha value given the material state .
 : param * * state : material state
 : returns : float"""

implementation: return self . k ( ** state ) / self . rho ( ** state ) / self . Cp ( ** state )


signature:
def _calc_a ( self , y_C , y_H , y_O , y_N , y_S ) :
    """Calculate the mean atomic weight for the specified element mass
 fractions .
 : param y _ C : Carbon mass fraction
 : param y _ H : Hydrogen mass fraction
 : param y _ O : Oxygen mass fraction
 : param y _ N : Nitrogen mass fraction
 : param y _ S : Sulphur mass fraction
 : returns : [ kg / kmol ] mean atomic weight
 See equation at bottom of page 538 of Merrick1983a ."""


signature:
def calculate ( self , ** state ) :
    """Calculate the enthalpy at the specified temperature and composition
 using equation 9 in Merrick1983b .
 : param T : [ K ] temperature
 : param y _ C : Carbon mass fraction
 : param y _ H : Hydrogen mass fraction
 : param y _ O : Oxygen mass fraction
 : param y _ N : Nitrogen mass fraction
 : param y _ S : Sulphur mass fraction
 : returns : [ J / kg ] enthalpy
 The * * state parameter contains the keyword argument ( s ) specified above
 that are used to describe the state of the material ."""

implementation:
T = state [ 'T' ]
y_C = state [ 'y_C' ]
y_H = state [ 'y_H' ]
y_O = state [ 'y_O' ]
y_N = state [ 'y_N' ]
y_S = state [ 'y_S' ]
a = self . _calc_a ( y_C , y_H , y_O , y_N , y_S ) / 1000
# kg / mol
result = ( R / a ) * ( 380 * self . _calc_g0 ( 380 / T ) + 3600 * self . _calc_g0 ( 1800 / T ) )
return result


signature:
def create_entity ( self , name , gl_structure , description = None ) :
    """Create an entity and add it to the model .
 : param name : The entity name .
 : param gl _ structure : The entity ' s general ledger structure .
 : param description : The entity description .
 : returns : The created entity ."""

implementation:
new_entity = Entity ( name , gl_structure , description = description )
self . entities . append ( new_entity )
return new_entity


signature:
def remove_entity ( self , name ) :
    """Remove an entity from the model .
 : param name : The name of the entity to remove ."""

implementation:
entity_to_remove = None
for e in self . entities :
    if e . name == name :
        entity_to_remove = e
if entity_to_remove is not None :
    self . entities . remove ( entity_to_remove )


signature:
def prepare_to_run ( self ) :
    """Prepare the model for execution ."""

implementation:
self . clock . reset ( )
for e in self . entities :
    e . prepare_to_run ( self . clock , self . period_count )


signature:
def run ( self ) :
    """Execute the model ."""

implementation:
self . prepare_to_run ( )
for i in range ( 0 , self . period_count ) :
    for e in self . entities :
        e . run ( self . clock )
    self . clock . tick ( )


signature:
def _create_element_list ( self ) :
    """Extract an alphabetically sorted list of elements from the
 material ' s compounds .
 : returns : Alphabetically sorted list of elements ."""

implementation:
element_set = stoich . elements ( self . compounds )
return sorted ( list ( element_set ) )


signature:
def add_assay ( self , name , assay ) :
    """Add an assay to the material .
 : param name : Assay name .
 : param assay : Numpy array containing the compound mass fractions for
 the assay . The sequence of the assay ' s elements must correspond to
 the sequence of the material ' s compounds ."""

implementation:
if not type ( assay ) is numpy . ndarray :
    raise Exception ( "Invalid assay. It must be a numpy array." )
elif not assay . shape == ( self . compound_count , ) :
    raise Exception ( "Invalid assay: It must have the same number of " "elements as the material has compounds." )
elif name in self . raw_assays . keys ( ) :
    raise Exception ( "Invalid assay: An assay with that name already " "exists." )
self . raw_assays [ name ] = assay
self . converted_assays [ name ] = assay


signature:
def create_package ( self , assay = None , mass = 0.0 , P = 1.0 , T = 25.0 , normalise = True ) :
    """Create a MaterialPackage based on the specified parameters .
 : param assay : Name of the assay to be used to create the package .
 : param mass : Package mass . [ kg ]
 : param P : Package pressure . [ atm ]
 : param T : Package temperature . [ ° C ]
 : param normalise : Indicates whether the assay must be normalised
 before creating the package .
 : returns : MaterialPackage object ."""

implementation:
if assay is None :
    return MaterialPackage ( self , self . create_empty_assay ( ) , P , T )
if normalise :
    assay_total = self . get_assay_total ( assay )
else :
    assay_total = 1.0
return MaterialPackage ( self , mass * self . converted_assays [ assay ] / assay_total , P , T , self . _isCoal ( assay ) , self . _get_HHV ( assay ) )


signature:
def create_stream ( self , assay = None , mfr = 0.0 , P = 1.0 , T = 25.0 , normalise = True ) :
    """Create a MaterialStream based on the specified parameters .
 : param assay : Name of the assay to be used to create the stream .
 : param mfr : Stream mass flow rate . [ kg / h ]
 : param P : Stream pressure . [ atm ]
 : param T : Stream temperature . [ ° C ]
 : param normalise : Indicates whether the assay must be normalised
 before creating the Stream .
 : returns : MaterialStream object ."""

implementation:
if assay is None :
    return MaterialStream ( self , self . create_empty_assay ( ) , P , T )
if normalise :
    assay_total = self . get_assay_total ( assay )
else :
    assay_total = 1.0
return MaterialStream ( self , mfr * self . converted_assays [ assay ] / assay_total , P , T , self . _isCoal ( assay ) , self . _get_HHV ( assay ) )


signature:
def _calculate_H ( self , T ) :
    """Calculate the enthalpy of the package at the specified temperature .
 : param T : Temperature . [ ° C ]
 : returns : Enthalpy . [ kWh ]"""

implementation:
if self . isCoal :
    return self . _calculate_Hfr_coal ( T )
H = 0.0
for compound in self . material . compounds :
    index = self . material . get_compound_index ( compound )
    dH = thermo . H ( compound , T , self . _compound_masses [ index ] )
    H = H + dH
return H


signature:
def _calculate_H_coal ( self , T ) :
    """Calculate the enthalpy of the package at the specified temperature , in
 case the material is coal .
 : param T : [ ° C ] temperature
 : returns : [ kWh ] enthalpy"""

implementation:
m_C = 0
# kg
m_H = 0
# kg
m_O = 0
# kg
m_N = 0
# kg
m_S = 0
# kg
H = 0.0
# kWh / h
for compound in self . material . compounds :
    index = self . material . get_compound_index ( compound )
    if stoich . element_mass_fraction ( compound , 'C' ) == 1.0 :
        m_C += self . _compound_masses [ index ]
    elif stoich . element_mass_fraction ( compound , 'H' ) == 1.0 :
        m_H += self . _compound_masses [ index ]
    elif stoich . element_mass_fraction ( compound , 'O' ) == 1.0 :
        m_O += self . _compound_masses [ index ]
    elif stoich . element_mass_fraction ( compound , 'N' ) == 1.0 :
        m_N += self . _compound_masses [ index ]
    elif stoich . element_mass_fraction ( compound , 'S' ) == 1.0 :
        m_S += self . _compound_masses [ index ]
    else :
        dH = thermo . H ( compound , T , self . _compound_masses [ index ] )
        H += dH
m_total = y_C + y_H + y_O + y_N + y_S
# kg / h
y_C = m_C / m_total
y_H = m_H / m_total
y_O = m_O / m_total
y_N = m_N / m_total
y_S = m_S / m_total
hmodel = coals . DafHTy ( )
H = hmodel . calculate ( T = T + 273.15 , y_C = y_C , y_H = y_H , y_O = y_O , y_N = y_N , y_S = y_S ) / 3.6e6
# kWh / kg
H298 = hmodel . calculate ( T = 298.15 , y_C = y_C , y_H = y_H , y_O = y_O , y_N = y_N , y_S = y_S ) / 3.6e6
# kWh / kg
Hdaf = H - H298 + self . _DH298
# kWh / kg
Hdaf *= m_total
# kWh
H += Hdaf
return H


signature:
def _calculate_T ( self , H ) :
    """Calculate the temperature of the package given the specified
 enthalpy using a secant algorithm .
 : param H : Enthalpy . [ kWh ]
 : returns : Temperature . [ ° C ]"""

implementation:
# Create the initial guesses for temperature .
x = list ( )
x . append ( self . _T )
x . append ( self . _T + 10.0 )
# Evaluate the enthalpy for the initial guesses .
y = list ( )
y . append ( self . _calculate_H ( x [ 0 ] ) - H )
y . append ( self . _calculate_H ( x [ 1 ] ) - H )
# Solve for temperature .
for i in range ( 2 , 50 ) :
    x . append ( x [ i - 1 ] - y [ i - 1 ] * ( ( x [ i - 1 ] - x [ i - 2 ] ) / ( y [ i - 1 ] - y [ i - 2 ] ) ) )
    y . append ( self . _calculate_H ( x [ i ] ) - H )
    if abs ( y [ i - 1 ] ) < 1.0e-5 :
        break
return x [ len ( x ) - 1 ]


signature:
def _is_compound_mass_tuple ( self , value ) :
    """Determines whether value is a tuple of the format
 ( compound ( str ) , mass ( float ) ) .
 : param value : The value to be tested .
 : returns : True or False"""

implementation:
if not type ( value ) is tuple :
    return False
elif not len ( value ) == 2 :
    return False
elif not type ( value [ 0 ] ) is str :
    return False
elif not type ( value [ 1 ] ) is float and not type ( value [ 1 ] ) is numpy . float64 and not type ( value [ 1 ] ) is numpy . float32 :
    return False
else :
    return True


signature:
def H ( self , H ) :
    """Set the enthalpy of the package to the specified value , and
 recalculate it ' s temperature .
 : param H : The new enthalpy value . [ kWh ]"""

implementation:
self . _H = H
self . _T = self . _calculate_T ( H )


signature:
def T ( self , T ) :
    """Set the temperature of the package to the specified value , and
 recalculate it ' s enthalpy .
 : param T : Temperature . [ ° C ]"""

implementation:
self . _T = T
self . _H = self . _calculate_H ( T )


signature:
def clone ( self ) :
    """Create a complete copy of the package .
 : returns : A new MaterialPackage object ."""

implementation:
result = copy . copy ( self )
result . _compound_masses = copy . deepcopy ( self . _compound_masses )
return result


signature:
def clear ( self ) :
    """Set all the compound masses in the package to zero .
 Set the pressure to 1 , the temperature to 25 and the enthalpy to zero ."""

implementation:
self . _compound_masses = self . _compound_masses * 0.0
self . _P = 1.0
self . _T = 25.0
self . _H = 0.0


signature:
def get_compound_mass ( self , compound ) :
    """Determine the mass of the specified compound in the package .
 : param compound : Formula and phase of a compound , e . g . " Fe2O3 [ S1 ] " .
 : returns : Mass . [ kg ]"""

implementation:
if compound in self . material . compounds :
    return self . _compound_masses [ self . material . get_compound_index ( compound ) ]
else :
    return 0.0


signature:
def get_compound_amounts ( self ) :
    """Determine the mole amounts of all the compounds .
 : returns : List of amounts . [ kmol ]"""

implementation:
result = self . _compound_masses * 1.0
for compound in self . material . compounds :
    index = self . material . get_compound_index ( compound )
    result [ index ] = stoich . amount ( compound , result [ index ] )
return result


signature:
def get_compound_amount ( self , compound ) :
    """Determine the mole amount of the specified compound .
 : returns : Amount . [ kmol ]"""

implementation:
index = self . material . get_compound_index ( compound )
return stoich . amount ( compound , self . _compound_masses [ index ] )


signature:
def amount ( self ) :
    """Determine the sum of mole amounts of all the compounds .
 : returns : Amount . [ kmol ]"""

implementation: return sum ( self . get_compound_amount ( c ) for c in self . material . compounds )


signature:
def get_element_masses ( self , elements = None ) :
    """Determine the masses of elements in the package .
 : returns : Array of element masses . [ kg ]"""

implementation:
if elements is None :
    elements = self . material . elements
result = numpy . zeros ( len ( elements ) )
for compound in self . material . compounds :
    result += self . get_compound_mass ( compound ) * numpy . array ( stoich . element_mass_fractions ( compound , elements ) )
return result


signature:
def get_element_mass_dictionary ( self ) :
    """Determine the masses of elements in the package and return as a
 dictionary .
 : returns : Dictionary of element symbols and masses . [ kg ]"""

implementation:
element_symbols = self . material . elements
element_masses = self . get_element_masses ( )
return { s : m for s , m in zip ( element_symbols , element_masses ) }


signature:
def get_element_mass ( self , element ) :
    """Determine the mass of the specified elements in the package .
 : returns : Masses . [ kg ]"""

implementation:
result = numpy . zeros ( 1 )
for compound in self . material . compounds :
    result += self . get_compound_mass ( compound ) * numpy . array ( stoich . element_mass_fractions ( compound , [ element ] ) )
return result [ 0 ]


signature:
def extract ( self , other ) :
    """Extract ' other ' from this package , modifying this package and
 returning the extracted material as a new package .
 : param other : Can be one of the following :
 * float : A mass equal to other is extracted from self . Self is
 reduced by other and the extracted package is returned as
 a new package .
 * tuple ( compound , mass ) : The other tuple specifies the mass
 of a compound to be extracted . It is extracted from self and
 the extracted mass is returned as a new package .
 * string : The ' other ' string specifies the compound to be
 extracted . All of the mass of that compound will be removed
 from self and a new package created with it .
 * Material : The ' other ' material specifies the list of
 compounds to extract .
 : returns : New MaterialPackage object ."""

implementation:
# Extract the specified mass .
if type ( other ) is float or type ( other ) is numpy . float64 or type ( other ) is numpy . float32 :
    return self . _extract_mass ( other )
# Extract the specified mass of the specified compound .
elif self . _is_compound_mass_tuple ( other ) :
    return self . _extract_compound_mass ( other [ 0 ] , other [ 1 ] )
# Extract all of the specified compound .
elif type ( other ) is str :
    return self . _extract_compound ( other )
# TODO : Test
# Extract all of the compounds of the specified material .
elif type ( other ) is Material :
    return self . _extract_material ( other )
# If not one of the above , it must be an invalid argument .
else :
    raise TypeError ( "Invalid extraction argument." )


signature:
def _calculate_Hfr ( self , T ) :
    """Calculate the enthalpy flow rate of the stream at the specified
 temperature .
 : param T : Temperature . [ ° C ]
 : returns : Enthalpy flow rate . [ kWh / h ]"""

implementation:
if self . isCoal :
    return self . _calculate_Hfr_coal ( T )
Hfr = 0.0
for compound in self . material . compounds :
    index = self . material . get_compound_index ( compound )
    dHfr = thermo . H ( compound , T , self . _compound_mfrs [ index ] )
    Hfr = Hfr + dHfr
return Hfr


signature:
def _calculate_DH298_coal ( self ) :
    """Calculate the enthalpy of formation of the dry - ash - free ( daf ) component of the coal .
 : returns : [ kWh / kg daf ] enthalpy of formation of daf coal"""

implementation:
m_C = 0
# kg
m_H = 0
# kg
m_O = 0
# kg
m_N = 0
# kg
m_S = 0
# kg
T = 25
Hin = 0.0
# kWh
for compound in self . material . compounds :
    index = self . material . get_compound_index ( compound )
    formula = compound . split ( '[' ) [ 0 ]
    if stoich . element_mass_fraction ( formula , 'C' ) == 1.0 :
        m_C += self . _compound_mfrs [ index ]
        Hin += thermo . H ( compound , T , self . _compound_mfrs [ index ] )
    elif stoich . element_mass_fraction ( formula , 'H' ) == 1.0 :
        m_H += self . _compound_mfrs [ index ]
        Hin += thermo . H ( compound , T , self . _compound_mfrs [ index ] )
    elif stoich . element_mass_fraction ( formula , 'O' ) == 1.0 :
        m_O += self . _compound_mfrs [ index ]
        Hin += thermo . H ( compound , T , self . _compound_mfrs [ index ] )
    elif stoich . element_mass_fraction ( formula , 'N' ) == 1.0 :
        m_N += self . _compound_mfrs [ index ]
        Hin += thermo . H ( compound , T , self . _compound_mfrs [ index ] )
    elif stoich . element_mass_fraction ( formula , 'S' ) == 1.0 :
        m_S += self . _compound_mfrs [ index ]
        Hin += thermo . H ( compound , T , self . _compound_mfrs [ index ] )
m_total = m_C + m_H + m_O + m_N + m_S
# kg
Hout = 0.0
# kWh
Hout += thermo . H ( 'CO2[G]' , T , cc ( m_C , 'C' , 'CO2' , 'C' ) )
Hout += thermo . H ( 'H2O[L]' , T , cc ( m_H , 'H' , 'H2O' , 'H' ) )
Hout += thermo . H ( 'O2[G]' , T , m_O )
Hout += thermo . H ( 'N2[G]' , T , m_N )
Hout += thermo . H ( 'SO2[G]' , T , cc ( m_S , 'S' , 'SO2' , 'S' ) )
Hout /= m_total
if self . HHV is None : # If no HHV is specified , calculate it from the proximate assay
# using C - H - O - N - S .
    HHV = ( Hout - Hin ) / m_total
    # kWh / kg daf
else : # If an HHV is specified , convert it from MJ / kg coal to kWh / kg daf .
    HHV = self . HHV / 3.6
    # kWh / kg coal
    HHV *= self . mfr / m_total
# kWh / kg daf
return HHV + Hout


signature:
def _calculate_Hfr_coal ( self , T ) :
    """Calculate the enthalpy flow rate of the stream at the specified
 temperature , in the case of it being coal .
 : param T : Temperature . [ ° C ]
 : returns : Enthalpy flow rate . [ kWh / h ]"""

implementation:
m_C = 0
# kg / h
m_H = 0
# kg / h
m_O = 0
# kg / h
m_N = 0
# kg / h
m_S = 0
# kg / h
Hfr = 0.0
# kWh / h
for compound in self . material . compounds :
    index = self . material . get_compound_index ( compound )
    formula = compound . split ( '[' ) [ 0 ]
    if stoich . element_mass_fraction ( formula , 'C' ) == 1.0 :
        m_C += self . _compound_mfrs [ index ]
    elif stoich . element_mass_fraction ( formula , 'H' ) == 1.0 :
        m_H += self . _compound_mfrs [ index ]
    elif stoich . element_mass_fraction ( formula , 'O' ) == 1.0 :
        m_O += self . _compound_mfrs [ index ]
    elif stoich . element_mass_fraction ( formula , 'N' ) == 1.0 :
        m_N += self . _compound_mfrs [ index ]
    elif stoich . element_mass_fraction ( formula , 'S' ) == 1.0 :
        m_S += self . _compound_mfrs [ index ]
    else :
        dHfr = thermo . H ( compound , T , self . _compound_mfrs [ index ] )
        Hfr += dHfr
m_total = m_C + m_H + m_O + m_N + m_S
# kg / h
y_C = m_C / m_total
y_H = m_H / m_total
y_O = m_O / m_total
y_N = m_N / m_total
y_S = m_S / m_total
hmodel = coals . DafHTy ( )
H = hmodel . calculate ( T = T + 273.15 , y_C = y_C , y_H = y_H , y_O = y_O , y_N = y_N , y_S = y_S ) / 3.6e6
# kWh / kg
H298 = hmodel . calculate ( T = 298.15 , y_C = y_C , y_H = y_H , y_O = y_O , y_N = y_N , y_S = y_S ) / 3.6e6
# kWh / kg
Hdaf = H - H298 + self . _DH298
# kWh / kg
Hdaf *= m_total
# kWh / h
Hfr += Hdaf
return Hfr


signature:
def _calculate_T ( self , Hfr ) :
    """Calculate the temperature of the stream given the specified
 enthalpy flow rate using a secant algorithm .
 : param H : Enthalpy flow rate . [ kWh / h ]
 : returns : Temperature . [ ° C ]"""

implementation:
# Create the initial guesses for temperature .
x = list ( )
x . append ( self . _T )
x . append ( self . _T + 10.0 )
# Evaluate the enthalpy for the initial guesses .
y = list ( )
y . append ( self . _calculate_Hfr ( x [ 0 ] ) - Hfr )
y . append ( self . _calculate_Hfr ( x [ 1 ] ) - Hfr )
# Solve for temperature .
for i in range ( 2 , 50 ) :
    x . append ( x [ i - 1 ] - y [ i - 1 ] * ( ( x [ i - 1 ] - x [ i - 2 ] ) / ( y [ i - 1 ] - y [ i - 2 ] ) ) )
    y . append ( self . _calculate_Hfr ( x [ i ] ) - Hfr )
    if abs ( y [ i - 1 ] ) < 1.0e-5 :
        break
return x [ len ( x ) - 1 ]


signature:
def _is_compound_mfr_temperature_tuple ( self , value ) :
    """Determines whether value is a tuple of the format
 ( compound ( str ) , mfr ( float ) , temperature ( float ) ) .
 : param value : The value to be tested .
 : returns : True or False"""

implementation:
if not type ( value ) is tuple :
    return False
elif not len ( value ) == 3 :
    return False
elif not type ( value [ 0 ] ) is str :
    return False
elif not type ( value [ 1 ] ) is float and not type ( value [ 1 ] ) is numpy . float64 and not type ( value [ 1 ] ) is numpy . float32 :
    return False
elif not type ( value [ 1 ] ) is float and not type ( value [ 1 ] ) is numpy . float64 and not type ( value [ 1 ] ) is numpy . float32 :
    return False
else :
    return True


signature:
def Hfr ( self , Hfr ) :
    """Set the enthalpy flow rate of the stream to the specified value , and
 recalculate it ' s temperature .
 : param H : The new enthalpy flow rate value . [ kWh / h ]"""

implementation:
self . _Hfr = Hfr
self . _T = self . _calculate_T ( Hfr )


signature:
def T ( self , T ) :
    """Set the temperature of the stream to the specified value , and
 recalculate it ' s enthalpy .
 : param T : Temperature . [ ° C ]"""

implementation:
self . _T = T
self . _Hfr = self . _calculate_Hfr ( T )


signature:
def HHV ( self , HHV ) :
    """Set the higher heating value of the stream to the specified value , and
 recalculate the formation enthalpy of the daf coal .
 : param HHV : MJ / kg coal , higher heating value"""

implementation:
self . _HHV = HHV
# MJ / kg coal
if self . isCoal :
    self . _DH298 = self . _calculate_DH298_coal ( )


signature:
def clone ( self ) :
    """Create a complete copy of the stream .
 : returns : A new MaterialStream object ."""

implementation:
result = copy . copy ( self )
result . _compound_mfrs = copy . deepcopy ( self . _compound_mfrs )
return result


signature:
def clear ( self ) :
    """Set all the compound mass flow rates in the stream to zero .
 Set the pressure to 1 , the temperature to 25 and the enthalpy to zero ."""

implementation:
self . _compound_mfrs = self . _compound_mfrs * 0.0
self . _P = 1.0
self . _T = 25.0
self . _H = 0.0


signature:
def get_compound_mfr ( self , compound ) :
    """Determine the mass flow rate of the specified compound in the stream .
 : param compound : Formula and phase of a compound , e . g . " Fe2O3 [ S1 ] " .
 : returns : Mass flow rate . [ kg / h ]"""

implementation:
if compound in self . material . compounds :
    return self . _compound_mfrs [ self . material . get_compound_index ( compound ) ]
else :
    return 0.0


signature:
def get_compound_afrs ( self ) :
    """Determine the amount flow rates of all the compounds .
 : returns : List of amount flow rates . [ kmol / h ]"""

implementation:
result = self . _compound_mfrs * 1.0
for compound in self . material . compounds :
    index = self . material . get_compound_index ( compound )
    result [ index ] = stoich . amount ( compound , result [ index ] )
return result


signature:
def get_compound_afr ( self , compound ) :
    """Determine the amount flow rate of the specified compound .
 : returns : Amount flow rate . [ kmol / h ]"""

implementation:
index = self . material . get_compound_index ( compound )
return stoich . amount ( compound , self . _compound_mfrs [ index ] )


signature:
def afr ( self ) :
    """Determine the sum of amount flow rates of all the compounds .
 : returns : Amount flow rate . [ kmol / h ]"""

implementation:
result = 0.0
for compound in self . material . compounds :
    result += self . get_compound_afr ( compound )
return result


signature:
def get_element_mfrs ( self , elements = None ) :
    """Determine the mass flow rates of elements in the stream .
 : returns : Array of element mass flow rates . [ kg / h ]"""

implementation:
if elements is None :
    elements = self . material . elements
result = numpy . zeros ( len ( elements ) )
for compound in self . material . compounds :
    result += self . get_compound_mfr ( compound ) * stoich . element_mass_fractions ( compound , elements )
return result


signature:
def get_element_mfr_dictionary ( self ) :
    """Determine the mass flow rates of elements in the stream and return as
 a dictionary .
 : returns : Dictionary of element symbols and mass flow rates . [ kg / h ]"""

implementation:
element_symbols = self . material . elements
element_mfrs = self . get_element_mfrs ( )
result = dict ( )
for s , mfr in zip ( element_symbols , element_mfrs ) :
    result [ s ] = mfr
return result


signature:
def get_element_mfr ( self , element ) :
    """Determine the mass flow rate of the specified elements in the stream .
 : returns : Mass flow rates . [ kg / h ]"""

implementation:
result = 0.0
for compound in self . material . compounds :
    formula = compound . split ( '[' ) [ 0 ]
    result += self . get_compound_mfr ( compound ) * stoich . element_mass_fraction ( formula , element )
return result


signature:
def extract ( self , other ) :
    """Extract ' other ' from this stream , modifying this stream and returning
 the extracted material as a new stream .
 : param other : Can be one of the following :
 * float : A mass flow rate equal to other is extracted from self . Self
 is reduced by other and the extracted stream is returned as
 a new stream .
 * tuple ( compound , mass ) : The other tuple specifies the mass flow
 rate of a compound to be extracted . It is extracted from self and
 the extracted mass flow rate is returned as a new stream .
 * string : The ' other ' string specifies the compound to be
 extracted . All of the mass flow rate of that compound will be
 removed from self and a new stream created with it .
 * Material : The ' other ' material specifies the list of
 compounds to extract .
 : returns : New MaterialStream object ."""

implementation:
# Extract the specified mass flow rate .
if type ( other ) is float or type ( other ) is numpy . float64 or type ( other ) is numpy . float32 :
    return self . _extract_mfr ( other )
# Extract the specified mass flow rateof the specified compound .
elif self . _is_compound_mfr_tuple ( other ) :
    return self . _extract_compound_mfr ( other [ 0 ] , other [ 1 ] )
# Extract all of the specified compound .
elif type ( other ) is str :
    return self . _extract_compound ( other )
# TODO : Test
# Extract all of the compounds of the specified material .
elif type ( other ) is Material :
    return self . _extract_material ( other )
# If not one of the above , it must be an invalid argument .
else :
    raise TypeError ( "Invalid extraction argument." )


signature:
def Gr ( L : float , Ts : float , Tf : float , beta : float , nu : float , g : float ) :
    """Calculate the Grashof number .
 : param L : [ m ] heat transfer surface characteristic length .
 : param Ts : [ K ] heat transfer surface temperature .
 : param Tf : [ K ] bulk fluid temperature .
 : param beta : [ 1 / K ] fluid coefficient of thermal expansion .
 : param nu : [ m2 / s ] fluid kinematic viscosity .
 : returns : float
 . . math : :
 \\ mathrm { Gr } = \\ frac { g \\ beta ( Ts - Tinf ) L ^ 3 } { \\ nu ^ 2}
 Characteristic dimensions :
 * vertical plate : vertical length
 * pipe : diameter
 * bluff body : diameter"""

implementation: return g * beta * ( Ts - Tf ) * L ** 3.0 / nu ** 2.0


signature:
def Re ( L : float , v : float , nu : float ) -> float :
    """Calculate the Reynolds number .
 : param L : [ m ] surface characteristic length .
 : param v : [ m / s ] fluid velocity relative to the object .
 : param nu : [ m2 / s ] fluid kinematic viscosity .
 : returns : float"""

implementation: return v * L / nu


signature:
def Ra ( L : float , Ts : float , Tf : float , alpha : float , beta : float , nu : float ) -> float :
    """Calculate the Ralleigh number .
 : param L : [ m ] heat transfer surface characteristic length .
 : param Ts : [ K ] heat transfer surface temperature .
 : param Tf : [ K ] bulk fluid temperature .
 : param alpha : [ m2 / s ] fluid thermal diffusivity .
 : param beta : [ 1 / K ] fluid coefficient of thermal expansion .
 : param nu : [ m2 / s ] fluid kinematic viscosity .
 : returns : float
 Ra = Gr * Pr
 Characteristic dimensions :
 * vertical plate : vertical length
 * pipe : diameter
 * bluff body : diameter"""

implementation: return g * beta * ( Ts - Tinf ) * L ** 3.0 / ( nu * alpha )


signature:
def Nu ( L : float , h : float , k : float ) -> float :
    """Calculate the Nusselt number .
 : param L : [ m ] heat transfer surface characteristic length .
 : param h : [ W / K / m2 ] convective heat transfer coefficient .
 : param k : [ W / K / m ] fluid thermal conductivity .
 : returns : float"""

implementation: return h * L / k


signature:
def Sh ( L : float , h : float , D : float ) -> float :
    """Calculate the Sherwood number .
 : param L : [ m ] mass transfer surface characteristic length .
 : param h : [ m / s ] mass transfer coefficient .
 : param D : [ m2 / s ] fluid mass diffusivity .
 : returns : float"""

implementation: return h * L / D


signature:
def create ( dataset , symbol , degree ) :
    """Create a model object from the data set for the property specified by
 the supplied symbol , using the specified polynomial degree .
 : param dataset : a DataSet object
 : param symbol : the symbol of the property to be described , e . g . ' rho '
 : param degree : the polynomial degree to use
 : returns : a new PolynomialModelT object"""

implementation:
x_vals = dataset . data [ 'T' ] . tolist ( )
y_vals = dataset . data [ symbol ] . tolist ( )
coeffs = np . polyfit ( x_vals , y_vals , degree )
result = PolynomialModelT ( dataset . material , dataset . names_dict [ symbol ] , symbol , dataset . display_symbols_dict [ symbol ] , dataset . units_dict [ symbol ] , None , [ dataset . name ] , coeffs )
result . state_schema [ 'T' ] [ 'min' ] = float ( min ( x_vals ) )
result . state_schema [ 'T' ] [ 'max' ] = float ( max ( x_vals ) )
return result


signature:
def calculate ( self , ** state ) :
    """Calculate the material physical property at the specified temperature
 in the units specified by the object ' s ' property _ units ' property .
 : param T : [ K ] temperature
 : returns : physical property value"""

implementation:
super ( ) . calculate ( ** state )
return np . polyval ( self . _coeffs , state [ 'T' ] )


signature:
def prepare_to_run ( self , clock , period_count ) :
    """Prepare the activity for execution .
 : param clock : The clock containing the execution start time and
 execution period information .
 : param period _ count : The total amount of periods this activity will be
 requested to be run for ."""

implementation:
if self . start_period_ix == - 1 and self . start_datetime != datetime . min : # Set the Start period index
    for i in range ( 0 , period_count ) :
        if clock . get_datetime_at_period_ix ( i ) > self . start_datetime :
            self . start_period_ix = i
            break
if self . start_period_ix == - 1 :
    self . start_period_ix = 0
if self . period_count == - 1 and self . end_datetime != datetime . max : # Set the Start date
    for i in range ( 0 , period_count ) :
        if clock . get_datetime_at_period_ix ( i ) > self . end_datetime :
            self . period_count = i - self . start_period_ix
            break
if self . period_count != - 1 :
    self . end_period_ix = self . start_period_ix + self . period_count
else :
    self . end_period_ix = self . start_period_ix + period_count


signature:
def create_component ( self , name , description = None ) :
    """Create a sub component in the business component .
 : param name : The new component ' s name .
 : param description : The new component ' s description .
 : returns : The created component ."""

implementation:
new_comp = Component ( name , self . gl , description = description )
new_comp . set_parent_path ( self . path )
self . components . append ( new_comp )
return new_comp


signature:
def remove_component ( self , name ) :
    """Remove a sub component from the component .
 : param name : The name of the component to remove ."""

implementation:
component_to_remove = None
for c in self . components :
    if c . name == name :
        component_to_remove = c
if component_to_remove is not None :
    self . components . remove ( component_to_remove )


signature:
def get_component ( self , name ) :
    """Retrieve a child component given its name .
 : param name : The name of the component .
 : returns : The component ."""

implementation: return [ c for c in self . components if c . name == name ] [ 0 ]


signature:
def add_activity ( self , activity ) :
    """Add an activity to the component .
 : param activity : The activity ."""

implementation:
self . gl . structure . validate_account_names ( activity . get_referenced_accounts ( ) )
self . activities . append ( activity )
activity . set_parent_path ( self . path )


signature:
def get_activity ( self , name ) :
    """Retrieve an activity given its name .
 : param name : The name of the activity .
 : returns : The activity ."""

implementation: return [ a for a in self . activities if a . name == name ] [ 0 ]


signature:
def prepare_to_run ( self , clock , period_count ) :
    """Prepare the component for execution .
 : param clock : The clock containing the execution start time and
 execution period information .
 : param period _ count : The total amount of periods this activity will be
 requested to be run for ."""

implementation:
for c in self . components :
    c . prepare_to_run ( clock , period_count )
for a in self . activities :
    a . prepare_to_run ( clock , period_count )


signature:
def run ( self , clock , generalLedger ) :
    """Execute the component at the current clock cycle .
 : param clock : The clock containing the current execution time and
 period information .
 : param generalLedger : The general ledger into which to create the
 transactions ."""

implementation:
for c in self . components :
    c . run ( clock , generalLedger )
for a in self . activities :
    a . run ( clock , generalLedger )


signature:
def prepare_to_run ( self , clock , period_count ) :
    """Prepare the entity for execution .
 : param clock : The clock containing the execution start time and
 execution period information .
 : param period _ count : The total amount of periods this activity will be
 requested to be run for ."""

implementation:
self . period_count = period_count
self . _exec_year_end_datetime = clock . get_datetime_at_period_ix ( period_count )
self . _prev_year_end_datetime = clock . start_datetime
self . _curr_year_end_datetime = clock . start_datetime + relativedelta ( years = 1 )
# Remove all the transactions
del self . gl . transactions [ : ]
for c in self . components :
    c . prepare_to_run ( clock , period_count )
self . negative_income_tax_total = 0


signature:
def run ( self , clock ) :
    """Execute the entity at the current clock cycle .
 : param clock : The clock containing the current execution time and
 period information ."""

implementation:
if clock . timestep_ix >= self . period_count :
    return
for c in self . components :
    c . run ( clock , self . gl )
self . _perform_year_end_procedure ( clock )


signature:
def count_with_multiplier ( groups , multiplier ) :
    """Update group counts with multiplier
 This is for handling atom counts on groups like ( OH ) 2
 : param groups : iterable of Group / Element
 : param multiplier : the number to multiply by"""

implementation:
counts = collections . defaultdict ( float )
for group in groups :
    for element , count in group . count ( ) . items ( ) :
        counts [ element ] += count * multiplier
return counts


signature:
def amounts ( masses ) :
    """Calculate the amounts from the specified compound masses .
 : param masses : [ kg ] dictionary , e . g . { ' SiO2 ' : 3.0 , ' FeO ' : 1.5}
 : returns : [ kmol ] dictionary"""

implementation: return { compound : amount ( compound , masses [ compound ] ) for compound in masses . keys ( ) }


signature:
def amount_fractions ( masses ) :
    """Calculate the mole fractions from the specified compound masses .
 : param masses : [ kg ] dictionary , e . g . { ' SiO2 ' : 3.0 , ' FeO ' : 1.5}
 : returns : [ mole fractions ] dictionary"""

implementation:
n = amounts ( masses )
n_total = sum ( n . values ( ) )
return { compound : n [ compound ] / n_total for compound in n . keys ( ) }


signature:
def masses ( amounts ) :
    """Calculate the masses from the specified compound amounts .
 : param masses : [ kmol ] dictionary , e . g . { ' SiO2 ' : 3.0 , ' FeO ' : 1.5}
 : returns : [ kg ] dictionary"""

implementation: return { compound : mass ( compound , amounts [ compound ] ) for compound in amounts . keys ( ) }


signature:
def mass_fractions ( amounts ) :
    """Calculate the mole fractions from the specified compound amounts .
 : param amounts : [ kmol ] dictionary , e . g . { ' SiO2 ' : 3.0 , ' FeO ' : 1.5}
 : returns : [ mass fractions ] dictionary"""

implementation:
m = masses ( amounts )
m_total = sum ( m . values ( ) )
return { compound : m [ compound ] / m_total for compound in m . keys ( ) }


signature:
def convert_compound ( mass , source , target , element ) :
    """Convert the specified mass of the source compound to the target using
 element as basis .
 : param mass : Mass of from _ compound . [ kg ]
 : param source : Formula and phase of the original compound , e . g .
 ' Fe2O3 [ S1 ] ' .
 : param target : Formula and phase of the target compound , e . g . ' Fe [ S1 ] ' .
 : param element : Element to use as basis for the conversion , e . g . ' Fe ' or
 : returns : Mass of target . [ kg ]"""

implementation:
# Perform the conversion .
target_mass_fraction = element_mass_fraction ( target , element )
if target_mass_fraction == 0.0 : # If target _ formula does not contain element , just return 0.0.
    return 0.0
else :
    source_mass_fraction = element_mass_fraction ( source , element )
    return mass * source_mass_fraction / target_mass_fraction


signature:
def element_mass_fraction ( compound , element ) :
    """Determine the mass fraction of an element in a chemical compound .
 : param compound : Formula of the chemical compound , ' FeCr2O4 ' .
 : param element : Element , e . g . ' Cr ' .
 : returns : Element mass fraction ."""

implementation:
coeff = stoichiometry_coefficient ( compound , element )
if coeff == 0.0 :
    return 0.0
formula_mass = molar_mass ( compound )
element_mass = molar_mass ( element )
return coeff * element_mass / formula_mass


signature:
def elements ( compounds ) :
    """Determine the set of elements present in a list of chemical compounds .
 The list of elements is sorted alphabetically .
 : param compounds : List of compound formulas and phases , e . g .
 [ ' Fe2O3 [ S1 ] ' , ' Al2O3 [ S1 ] ' ] .
 : returns : List of elements ."""

implementation:
elementlist = [ parse_compound ( compound ) . count ( ) . keys ( ) for compound in compounds ]
return set ( ) . union ( * elementlist )


signature:
def molar_mass ( compound = '' ) :
    """Determine the molar mass of a chemical compound .
 The molar mass is usually the mass of one mole of the substance , but here
 it is the mass of 1000 moles , since the mass unit used in auxi is kg .
 : param compound : Formula of a chemical compound , e . g . ' Fe2O3 ' .
 : returns : Molar mass . [ kg / kmol ]"""

implementation:
result = 0.0
if compound is None or len ( compound ) == 0 :
    return result
compound = compound . strip ( )
parsed = parse_compound ( compound )
return parsed . molar_mass ( )


signature:
def stoichiometry_coefficient ( compound , element ) :
    """Determine the stoichiometry coefficient of an element in a chemical
 compound .
 : param compound : Formula of a chemical compound , e . g . ' SiO2 ' .
 : param element : Element , e . g . ' Si ' .
 : returns : Stoichiometry coefficient ."""

implementation:
stoichiometry = parse_compound ( compound . strip ( ) ) . count ( )
return stoichiometry [ element ]


signature:
def stoichiometry_coefficients ( compound , elements ) :
    """Determine the stoichiometry coefficients of the specified elements in
 the specified chemical compound .
 : param compound : Formula of a chemical compound , e . g . ' SiO2 ' .
 : param elements : List of elements , e . g . [ ' Si ' , ' O ' , ' C ' ] .
 : returns : List of stoichiometry coefficients ."""

implementation:
stoichiometry = parse_compound ( compound . strip ( ) ) . count ( )
return [ stoichiometry [ element ] for element in elements ]


signature:
def add_assay ( self , name , assay ) :
    """Add an assay to the material .
 : param name : The name of the new assay .
 : param assay : A numpy array containing the size class mass fractions
 for the assay . The sequence of the assay ' s elements must correspond
 to the sequence of the material ' s size classes ."""

implementation:
if not type ( assay ) is numpy . ndarray :
    raise Exception ( "Invalid assay. It must be a numpy array." )
elif not assay . shape == ( self . size_class_count , ) :
    raise Exception ( "Invalid assay: It must have the same number of elements " "as the material has size classes." )
elif name in self . assays . keys ( ) :
    raise Exception ( "Invalid assay: An assay with that name already exists." )
self . assays [ name ] = assay


signature:
def create_package ( self , assay = None , mass = 0.0 , normalise = True ) :
    """Create a MaterialPackage based on the specified parameters .
 : param assay : The name of the assay based on which the package must be
 created .
 : param mass : [ kg ] The mass of the package .
 : param normalise : Indicates whether the assay must be normalised before
 creating the package .
 : returns : The created MaterialPackage ."""

implementation:
if assay is None :
    return MaterialPackage ( self , self . create_empty_assay ( ) )
if normalise :
    assay_total = self . get_assay_total ( assay )
else :
    assay_total = 1.0
return MaterialPackage ( self , mass * self . assays [ assay ] / assay_total )


signature:
def extract ( self , other ) :
    """Extract ' other ' from self , modifying self and returning the extracted
 material as a new package .
 : param other : Can be one of the following :
 * float : A mass equal to other is extracted from self . Self is
 reduced by other and the extracted package is returned as a new
 package .
 * tuple ( size class , mass ) : The other tuple specifies the mass
 of a size class to be extracted . It is extracted from self and
 the extracted mass is returned as a new package .
 * string : The ' other ' string specifies the size class to be
 extracted . All of the mass of that size class will be removed
 from self and a new package created with it .
 : returns : A new material package containing the material that was
 extracted from self ."""

implementation:
# Extract the specified mass .
if type ( other ) is float or type ( other ) is numpy . float64 or type ( other ) is numpy . float32 :
    if other > self . get_mass ( ) :
        raise Exception ( "Invalid extraction operation. " "Cannot extract a mass larger than the package's mass." )
    fraction_to_subtract = other / self . get_mass ( )
    result = MaterialPackage ( self . material , self . size_class_masses * fraction_to_subtract )
    self . size_class_masses = self . size_class_masses * ( 1.0 - fraction_to_subtract )
    return result
# Extract the specified mass of the specified size class .
elif self . _is_size_class_mass_tuple ( other ) :
    index = self . material . get_size_class_index ( other [ 0 ] )
    if other [ 1 ] > self . size_class_masses [ index ] :
        raise Exception ( "Invalid extraction operation. " "Cannot extract a size class mass larger than what the " "package contains." )
    self . size_class_masses [ index ] = self . size_class_masses [ index ] - other [ 1 ]
    resultarray = self . size_class_masses * 0.0
    resultarray [ index ] = other [ 1 ]
    result = MaterialPackage ( self . material , resultarray )
    return result
# Extract all of the specified size class .
elif type ( other ) is str :
    index = self . material . get_size_class_index ( float ( other ) )
    result = self * 0.0
    result . size_class_masses [ index ] = self . size_class_masses [ index ]
    self . size_class_masses [ index ] = 0.0
    return result
# If not one of the above , it must be an invalid argument .
else :
    raise TypeError ( "Invalid extraction argument." )


signature:
def add_to ( self , other ) :
    """Add another psd material package to this material package .
 : param other : The other material package ."""

implementation:
# Add another package .
if type ( other ) is MaterialPackage : # Packages of the same material .
    if self . material == other . material :
        self . size_class_masses = self . size_class_masses + other . size_class_masses
    else : # Packages of different materials .
        for size_class in other . material . size_classes :
            if size_class not in self . material . size_classes :
                raise Exception ( "Packages of '" + other . material . name + "' cannot be added to packages of '" + self . material . name + "'. The size class '" + size_class + "' was not found in '" + self . material . name + "'." )
            self . add_to ( ( size_class , other . get_size_class_mass ( size_class ) ) )
# Add the specified mass of the specified size class .
elif self . _is_size_class_mass_tuple ( other ) : # Added material variables .
    size_class = other [ 0 ]
    compound_index = self . material . get_size_class_index ( size_class )
    mass = other [ 1 ]
    # Create the result package .
    self . size_class_masses [ compound_index ] = self . size_class_masses [ compound_index ] + mass
# If not one of the above , it must be an invalid argument .
else :
    raise TypeError ( "Invalid addition argument." )


signature:
def run ( self , clock , generalLedger ) :
    """Execute the activity at the current clock cycle .
 : param clock : The clock containing the current execution time and
 period information .
 : param generalLedger : The general ledger into which to create the
 transactions ."""

implementation:
if not self . _meet_execution_criteria ( clock . timestep_ix ) :
    return
generalLedger . create_transaction ( self . description if self . description is not None else self . name , description = '' , tx_date = clock . get_datetime ( ) , dt_account = self . dt_account , cr_account = self . cr_account , source = self . path , amount = self . amount )


signature:
def prepare_to_run ( self , clock , period_count ) :
    """Prepare the activity for execution .
 : param clock : The clock containing the execution start time and
 execution period information .
 : param period _ count : The total amount of periods this activity will be
 requested to be run for ."""

implementation:
super ( BasicLoanActivity , self ) . prepare_to_run ( clock , period_count )
self . _months_executed = 0
self . _amount_left = self . amount


implementation:
if not self . _meet_execution_criteria ( clock . timestep_ix ) :
    return
if self . description is None :
    tx_name = self . name
else :
    tx_name = self . description
if self . _months_executed == 0 :
    generalLedger . create_transaction ( tx_name , description = 'Make a loan' , tx_date = clock . get_datetime ( ) , dt_account = self . bank_account , cr_account = self . loan_account , source = self . path , amount = self . amount )
else :
    curr_interest_amount = ( self . _amount_left * self . interest_rate ) / 12.0
    generalLedger . create_transaction ( tx_name , description = 'Consider interest' , tx_date = clock . get_datetime ( ) , dt_account = self . interest_account , cr_account = self . loan_account , source = self . path , amount = curr_interest_amount )
    generalLedger . create_transaction ( tx_name , description = 'Pay principle' , tx_date = clock . get_datetime ( ) , dt_account = self . loan_account , cr_account = self . bank_account , source = self . path , amount = self . _monthly_payment )
    self . _amount_left += curr_interest_amount - self . _monthly_payment
self . _months_executed += self . interval


signature:
def get_datetime_at_period_ix ( self , ix ) :
    """Get the datetime at a given period .
 : param period : The index of the period .
 : returns : The datetime ."""

implementation:
if self . timestep_period_duration == TimePeriod . millisecond :
    return self . start_datetime + timedelta ( milliseconds = ix )
elif self . timestep_period_duration == TimePeriod . second :
    return self . start_datetime + timedelta ( seconds = ix )
elif self . timestep_period_duration == TimePeriod . minute :
    return self . start_datetime + timedelta ( minutes = ix )
elif self . timestep_period_duration == TimePeriod . hour :
    return self . start_datetime + timedelta ( hours = ix )
elif self . timestep_period_duration == TimePeriod . day :
    return self . start_datetime + relativedelta ( days = ix )
elif self . timestep_period_duration == TimePeriod . week :
    return self . start_datetime + relativedelta ( days = ix * 7 )
elif self . timestep_period_duration == TimePeriod . month :
    return self . start_datetime + relativedelta ( months = ix )
elif self . timestep_period_duration == TimePeriod . year :
    return self . start_datetime + relativedelta ( years = ix )


signature:
def _get_default_data_path_ ( ) :
    """Calculate the default path in which thermochemical data is stored .
 : returns : Default path ."""

implementation:
module_path = os . path . dirname ( sys . modules [ __name__ ] . __file__ )
data_path = os . path . join ( module_path , r'data/rao' )
data_path = os . path . abspath ( data_path )
return data_path


signature:
def _read_compound_from_factsage_file_ ( file_name ) :
    """Build a dictionary containing the factsage thermochemical data of a
 compound by reading the data from a file .
 : param file _ name : Name of file to read the data from .
 : returns : Dictionary containing compound data ."""

implementation:
with open ( file_name ) as f :
    lines = f . readlines ( )
compound = { 'Formula' : lines [ 0 ] . split ( ' ' ) [ 1 ] }
# FIXME : replace with logging
print ( compound [ 'Formula' ] )
compound [ 'Phases' ] = phs = { }
started = False
phaseold = 'zz'
recordold = '0'
for line in lines :
    if started :
        if line . startswith ( '_' ) : # line indicating end of data
            break
        line = line . replace ( ' 298 ' , ' 298.15 ' )
        line = line . replace ( ' - ' , ' ' )
        while '  ' in line :
            line = line . replace ( '  ' , ' ' )
        line = line . replace ( ' \n' , '' )
        line = line . replace ( '\n' , '' )
        strings = line . split ( ' ' )
        if len ( strings ) < 2 : # empty line
            continue
        phase = strings [ 0 ]
        if phase != phaseold : # new phase detected
            phaseold = phase
            ph = phs [ phase ] = { }
            ph [ 'Symbol' ] = phase
            ph [ 'DHref' ] = float ( strings [ 2 ] )
            ph [ 'Sref' ] = float ( strings [ 3 ] )
            cprecs = ph [ 'Cp_records' ] = { }
            record = strings [ 1 ]
            if record != recordold : # new record detected
                recordold = record
                Tmax = float ( strings [ len ( strings ) - 1 ] )
                cprecs [ Tmax ] = { }
                cprecs [ Tmax ] [ 'Tmin' ] = float ( strings [ len ( strings ) - 2 ] )
                cprecs [ Tmax ] [ 'Tmax' ] = float ( strings [ len ( strings ) - 1 ] )
                cprecs [ Tmax ] [ 'Terms' ] = [ ]
                t = { 'Coefficient' : float ( strings [ 4 ] ) , 'Exponent' : float ( strings [ 5 ] ) }
                cprecs [ Tmax ] [ 'Terms' ] . append ( t )
                if len ( strings ) == 10 :
                    t = { 'Coefficient' : float ( strings [ 6 ] ) , 'Exponent' : float ( strings [ 7 ] ) }
                    cprecs [ Tmax ] [ 'Terms' ] . append ( t )
            else : # old record detected
                t = { 'Coefficient' : float ( strings [ 2 ] ) , 'Exponent' : float ( strings [ 3 ] ) }
                cprecs [ Tmax ] [ 'Terms' ] . append ( t )
                if len ( strings ) == 8 :
                    t = { 'Coefficient' : float ( strings [ 4 ] ) , 'Exponent' : float ( strings [ 5 ] ) }
                    cprecs [ Tmax ] [ 'Terms' ] . append ( t )
        else : # old phase detected
            ph = phs [ phase ]
            record = strings [ 1 ]
            if record != recordold : # new record detected
                recordold = record
                Tmax = float ( strings [ len ( strings ) - 1 ] )
                cprecs = ph [ 'Cp_records' ]
                cprecs [ Tmax ] = { }
                cprecs [ Tmax ] [ 'Tmin' ] = float ( strings [ len ( strings ) - 2 ] )
                cprecs [ Tmax ] [ 'Tmax' ] = float ( strings [ len ( strings ) - 1 ] )
                cprecs [ Tmax ] [ 'Terms' ] = [ ]
                t = { 'Coefficient' : float ( strings [ 2 ] ) , 'Exponent' : float ( strings [ 3 ] ) }
                cprecs [ Tmax ] [ 'Terms' ] . append ( t )
                if len ( strings ) == 8 :
                    t = { 'Coefficient' : float ( strings [ 4 ] ) , 'Exponent' : float ( strings [ 5 ] ) }
                    cprecs [ Tmax ] [ 'Terms' ] . append ( t )
            else : # old record detected
                t = { 'Coefficient' : float ( strings [ 2 ] ) , 'Exponent' : float ( strings [ 3 ] ) }
                cprecs [ Tmax ] [ 'Terms' ] . append ( t )
                if len ( strings ) == 8 :
                    t = { 'Coefficient' : float ( strings [ 4 ] ) , 'Exponent' : float ( strings [ 5 ] ) }
                    cprecs [ Tmax ] [ 'Terms' ] . append ( t )
    if line . startswith ( '_' ) : # line indicating the start of the data
        started = True
for name , ph in phs . items ( ) :
    cprecs = ph [ 'Cp_records' ]
    first = cprecs [ min ( cprecs . keys ( ) ) ]
    first [ 'Tmin' ] = 298.15
return compound


signature:
def _split_compound_string_ ( compound_string ) :
    """Split a compound ' s combined formula and phase into separate strings for
 the formula and phase .
 : param compound _ string : Formula and phase of a chemical compound , e . g .
 ' SiO2 [ S1 ] ' .
 : returns : Formula of chemical compound .
 : returns : Phase of chemical compound ."""

implementation:
formula = compound_string . replace ( ']' , '' ) . split ( '[' ) [ 0 ]
phase = compound_string . replace ( ']' , '' ) . split ( '[' ) [ 1 ]
return formula , phase


signature:
def _finalise_result_ ( compound , value , mass ) :
    """Convert the value to its final form by unit conversions and multiplying
 by mass .
 : param compound : Compound object .
 : param value : [ J / mol ] Value to be finalised .
 : param mass : [ kg ] Mass of compound .
 : returns : [ kWh ] Finalised value ."""

implementation:
result = value / 3.6E6
# J / x - > kWh / x
result = result / compound . molar_mass
# x / mol - > x / kg
result = result * mass
# x / kg - > x
return result


signature:
def write_compound_to_auxi_file ( directory , compound ) :
    """Writes a compound to an auxi file at the specified directory .
 : param dir : The directory .
 : param compound : The compound ."""

implementation:
file_name = "Compound_" + compound . formula + ".json"
with open ( os . path . join ( directory , file_name ) , 'w' ) as f :
    f . write ( str ( compound ) )


signature:
def load_data_factsage ( path = '' ) :
    """Load all the thermochemical data factsage files located at a path .
 : param path : Path at which the data files are located ."""

implementation:
compounds . clear ( )
if path == '' :
    path = default_data_path
if not os . path . exists ( path ) :
    warnings . warn ( 'The specified data file path does not exist. (%s)' % path )
    return
files = glob . glob ( os . path . join ( path , 'Compound_*.txt' ) )
for file in files :
    compound = Compound ( _read_compound_from_factsage_file_ ( file ) )
    compounds [ compound . formula ] = compound


signature:
def load_data_auxi ( path = '' ) :
    """Load all the thermochemical data auxi files located at a path .
 : param path : Path at which the data files are located ."""

implementation:
compounds . clear ( )
if path == '' :
    path = default_data_path
if not os . path . exists ( path ) :
    warnings . warn ( 'The specified data file path does not exist. (%s)' % path )
    return
files = glob . glob ( os . path . join ( path , 'Compound_*.json' ) )
for file in files :
    compound = Compound . read ( file )
    compounds [ compound . formula ] = compound


signature:
def list_compounds ( ) :
    """List all compounds that are currently loaded in the thermo module , and
 their phases ."""

implementation:
print ( 'Compounds currently loaded:' )
for compound in sorted ( compounds . keys ( ) ) :
    phases = compounds [ compound ] . get_phase_list ( )
    print ( '%s: %s' % ( compound , ', ' . join ( phases ) ) )


signature:
def Cp ( compound_string , T , mass = 1.0 ) :
    """Calculate the heat capacity of the compound for the specified temperature
 and mass .
 : param compound _ string : Formula and phase of chemical compound , e . g .
 ' Fe2O3 [ S1 ] ' .
 : param T : [ ° C ] temperature
 : param mass : [ kg ]
 : returns : [ kWh / K ] Heat capacity ."""

implementation:
formula , phase = _split_compound_string_ ( compound_string )
TK = T + 273.15
compound = compounds [ formula ]
result = compound . Cp ( phase , TK )
return _finalise_result_ ( compound , result , mass )


signature:
def Cp ( self , T ) :
    """Calculate the heat capacity of the compound phase .
 : param T : [ K ] temperature
 : returns : [ J / mol / K ] Heat capacity ."""

implementation:
result = 0.0
for c , e in zip ( self . _coefficients , self . _exponents ) :
    result += c * T ** e
return result


signature:
def H ( self , T ) :
    """Calculate the portion of enthalpy of the compound phase covered by this
 Cp record .
 : param T : [ K ] temperature
 : returns : [ J / mol ] Enthalpy ."""

implementation:
result = 0.0
if T < self . Tmax :
    lT = T
else :
    lT = self . Tmax
Tref = self . Tmin
for c , e in zip ( self . _coefficients , self . _exponents ) : # Analytically integrate Cp ( T ) .
    if e == - 1.0 :
        result += c * math . log ( lT / Tref )
    else :
        result += c * ( lT ** ( e + 1.0 ) - Tref ** ( e + 1.0 ) ) / ( e + 1.0 )
return result


signature:
def S ( self , T ) :
    """Calculate the portion of entropy of the compound phase covered by this
 Cp record .
 : param T : [ K ] temperature
 : returns : Entropy . [ J / mol / K ]"""

implementation:
result = 0.0
if T < self . Tmax :
    lT = T
else :
    lT = self . Tmax
Tref = self . Tmin
for c , e in zip ( self . _coefficients , self . _exponents ) : # Create a modified exponent to analytically integrate Cp ( T ) / T
# instead of Cp ( T ) .
    e_modified = e - 1.0
    if e_modified == - 1.0 :
        result += c * math . log ( lT / Tref )
    else :
        e_mod = e_modified + 1.0
        result += c * ( lT ** e_mod - Tref ** e_mod ) / e_mod
return result


signature:
def Cp ( self , T ) :
    """Calculate the heat capacity of the compound phase at the specified
 temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol / K ] The heat capacity of the compound phase ."""

implementation:
# TODO : Fix str / float conversion
for Tmax in sorted ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] ) :
    if T < Tmax :
        return self . _Cp_records [ str ( Tmax ) ] . Cp ( T ) + self . Cp_mag ( T )
Tmax = max ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] )
return self . _Cp_records [ str ( Tmax ) ] . Cp ( Tmax ) + self . Cp_mag ( T )


signature:
def Cp_mag ( self , T ) :
    """Calculate the phase ' s magnetic contribution to heat capacity at the
 specified temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol / K ] The magnetic heat capacity of the compound phase .
 Dinsdale , A . T . ( 1991 ) . SGTE data for pure elements . Calphad , 15(4 ) ,
 317–425 . http : / / doi . org / 10.1016/0364-5916(91)90030 - N"""

implementation:
tau = T / self . Tc_mag
if tau <= 1.0 :
    c = ( self . _B_mag * ( 2 * tau ** 3 + 2 * tau ** 9 / 3 + 2 * tau ** 15 / 5 ) ) / self . _D_mag
else :
    c = ( 2 * tau ** - 5 + 2 * tau ** - 15 / 3 + 2 * tau ** - 25 / 5 ) / self . _D_mag
result = R * math . log ( self . beta0_mag + 1 ) * c
return result


signature:
def H ( self , T ) :
    """Calculate the enthalpy of the compound phase at the specified
 temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol ] The enthalpy of the compound phase ."""

implementation:
result = self . DHref
for Tmax in sorted ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] ) :
    result += self . _Cp_records [ str ( Tmax ) ] . H ( T )
    if T <= Tmax :
        return result + self . H_mag ( T )
# Extrapolate beyond the upper limit by using a constant heat capacity .
Tmax = max ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] )
result += self . Cp ( Tmax ) * ( T - Tmax )
return result + self . H_mag ( T )


signature:
def H_mag ( self , T ) :
    """Calculate the phase ' s magnetic contribution to enthalpy at the
 specified temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol ] The magnetic enthalpy of the compound phase .
 Dinsdale , A . T . ( 1991 ) . SGTE data for pure elements . Calphad , 15(4 ) ,
 317–425 . http : / / doi . org / 10.1016/0364-5916(91)90030 - N"""

implementation:
tau = T / self . Tc_mag
if tau <= 1.0 :
    h = ( - self . _A_mag / tau + self . _B_mag * ( tau ** 3 / 2 + tau ** 9 / 15 + tau ** 15 / 40 ) ) / self . _D_mag
else :
    h = - ( tau ** - 5 / 2 + tau ** - 15 / 21 + tau ** - 25 / 60 ) / self . _D_mag
return R * T * math . log ( self . beta0_mag + 1 ) * h


signature:
def S ( self , T ) :
    """Calculate the entropy of the compound phase at the specified
 temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol / K ] The entropy of the compound phase ."""

implementation:
result = self . Sref
for Tmax in sorted ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] ) :
    result += self . _Cp_records [ str ( Tmax ) ] . S ( T )
    if T <= Tmax :
        return result + self . S_mag ( T )
# Extrapolate beyond the upper limit by using a constant heat capacity .
Tmax = max ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] )
result += self . Cp ( Tmax ) * math . log ( T / Tmax )
return result + self . S_mag ( T )


signature:
def S_mag ( self , T ) :
    """Calculate the phase ' s magnetic contribution to entropy at the
 specified temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol / K ] The magnetic entropy of the compound phase .
 Dinsdale , A . T . ( 1991 ) . SGTE data for pure elements . Calphad , 15(4 ) ,
 317–425 . http : / / doi . org / 10.1016/0364-5916(91)90030 - N"""


signature:
def G ( self , T ) :
    """Calculate the heat capacity of the compound phase at the specified
 temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol ] The Gibbs free energy of the compound phase ."""

implementation:
h = self . DHref
s = self . Sref
for Tmax in sorted ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] ) :
    h = h + self . _Cp_records [ str ( Tmax ) ] . H ( T )
    s = s + self . _Cp_records [ str ( Tmax ) ] . S ( T )
    if T <= Tmax :
        return h - T * s + self . G_mag ( T )
# Extrapolate beyond the upper limit by using a constant heat capacity .
Tmax = max ( [ float ( TT ) for TT in self . _Cp_records . keys ( ) ] )
h = h + self . Cp ( Tmax ) * ( T - Tmax )
s = s + self . Cp ( Tmax ) * math . log ( T / Tmax )
return h - T * s + self . G_mag ( T )


signature:
def G_mag ( self , T ) :
    """Calculate the phase ' s magnetic contribution to Gibbs energy at the
 specified temperature .
 : param T : [ K ] temperature
 : returns : [ J / mol ] The magnetic Gibbs energy of the compound phase .
 Dinsdale , A . T . ( 1991 ) . SGTE data for pure elements . Calphad , 15(4 ) ,
 317–425 . http : / / doi . org / 10.1016/0364-5916(91)90030 - N"""

implementation:
tau = T / self . Tc_mag
if tau <= 1.0 :
    g = 1 - ( self . _A_mag / tau + self . _B_mag * ( tau ** 3 / 6 + tau ** 9 / 135 + tau ** 15 / 600 ) ) / self . _D_mag
else :
    g = - ( tau ** - 5 / 10 + tau ** - 15 / 315 + tau ** - 25 / 1500 ) / self . _D_mag
return R * T * math . log ( self . beta0_mag + 1 ) * g


signature:
def Cp ( self , phase , T ) :
    """Calculate the heat capacity of a phase of the compound at a specified
 temperature .
 : param phase : A phase of the compound , e . g . ' S ' , ' L ' , ' G ' .
 : param T : [ K ] temperature
 : returns : [ J / mol / K ] Heat capacity ."""

implementation:
if phase not in self . _phases :
    raise Exception ( "The phase '%s' was not found in compound '%s'." % ( phase , self . formula ) )
return self . _phases [ phase ] . Cp ( T )


signature:
def H ( self , phase , T ) :
    """Calculate the enthalpy of a phase of the compound at a specified
 temperature .
 : param phase : A phase of the compound , e . g . ' S ' , ' L ' , ' G ' .
 : param T : [ K ] temperature
 : returns : [ J / mol ] Enthalpy ."""

implementation:
try :
    return self . _phases [ phase ] . H ( T )
except KeyError :
    raise Exception ( "The phase '{}' was not found in compound '{}'." . format ( phase , self . formula ) )


signature:
def _create_polynomial_model ( name : str , symbol : str , degree : int , ds : DataSet , dss : dict ) :
    """Create a polynomial model to describe the specified property based on the
 specified data set , and save it to a . json file .
 : param name : material name .
 : param symbol : property symbol .
 : param degree : polynomial degree .
 : param ds : the source data set .
 : param dss : dictionary of all datasets ."""

implementation:
ds_name = ds . name . split ( "." ) [ 0 ] . lower ( )
file_name = f"{name.lower()}-{symbol.lower()}-polynomialmodelt-{ds_name}"
newmod = PolynomialModelT . create ( ds , symbol , degree )
newmod . plot ( dss , _path ( f"data/{file_name}.pdf" ) , False )
newmod . write ( _path ( f"data/{file_name}.json" ) )


signature:
def _create_air ( ) :
    """Create a dictionary of datasets and a material object for air .
 : return : ( Material , { str , DataSet } )"""

implementation:
name = "Air"
namel = name . lower ( )
mm = 28.9645
# g / mol
ds_dict = _create_ds_dict ( [ "dataset-air-lienhard2015" , "dataset-air-lienhard2018" ] )
active_ds = "dataset-air-lienhard2018"
# create polynomial models to describe material properties
# comment it out after model creation is complete , so that it does not
# run every time during use .
# _ create _ polynomial _ model ( name , " Cp " , 13 , ds _ dict [ active _ ds ] , ds _ dict )
# _ create _ polynomial _ model ( name , " k " , 8 , ds _ dict [ active _ ds ] , ds _ dict )
# _ create _ polynomial _ model ( name , " mu " , 8 , ds _ dict [ active _ ds ] , ds _ dict )
# _ create _ polynomial _ model ( name , " rho " , 14 , ds _ dict [ active _ ds ] , ds _ dict )
# IgRhoT ( mm , 101325.0 ) . plot ( ds _ dict , _ path ( f " data / { namel } - rho - igrhot . pdf " ) )
model_dict = { "rho" : IgRhoT ( mm , 101325.0 ) , "beta" : IgBetaT ( ) }
model_type = "polynomialmodelt"
for property in [ "Cp" , "mu" , "k" ] :
    name = f"data/{namel}-{property.lower()}-{model_type}-{active_ds}.json"
    model_dict [ property ] = PolynomialModelT . read ( _path ( name ) )
material = Material ( name , StateOfMatter . gas , model_dict )
return material , ds_dict


signature:
def calculate ( self , ** state ) :
    """Calculate dynamic viscosity at the specified temperature and
 composition :
 : param T : [ K ] temperature
 : param x : [ mole fraction ] composition dictionary , e . g .
 { ' CO ' : 0.25 , ' CO2 ' : 0.25 , ' N2 ' : 0.25 , ' O2 ' : 0.25}
 : returns : [ Pa . s ] dynamic viscosity
 The * * state parameter contains the keyword argument ( s ) specified above
 that are used to describe the state of the material ."""

implementation:
def phi ( i , j , mu_i , mu_j ) :
    M_i = M ( i )
    M_j = M ( j )
    result = ( 1.0 + ( mu_i / mu_j ) ** 0.5 * ( M_j / M_i ) ** 0.25 ) ** 2.0
    result /= ( 4.0 / sqrt ( 2.0 ) )
    result /= ( 1.0 + M_i / M_j ) ** 0.5
    return result
T = state [ 'T' ]
x = state [ 'x' ]
# normalise mole fractions
x_total = sum ( [ x for compound , x in x . items ( ) if compound in materials ] )
x = { compound : x [ compound ] / x_total for compound in x . keys ( ) if compound in materials }
result = 0.0
# Pa . s
mu = { i : materials [ i ] . mu ( T = T ) for i in x . keys ( ) }
for i in x . keys ( ) :
    sum_i = 0.0
    for j in x . keys ( ) :
        if j == i :
            continue
        sum_i += x [ j ] * phi ( i , j , mu [ i ] , mu [ j ] )
    result += x [ i ] * mu [ i ] / ( x [ i ] + sum_i )
return result


implementation:
T = state [ 'T' ]
x = state [ 'x' ]
# normalise mole fractions
x_total = sum ( [ x for compound , x in x . items ( ) if compound in materials ] )
x = { compound : x [ compound ] / x_total for compound in x . keys ( ) if compound in materials }
mu = { i : materials [ i ] . mu ( T = T ) for i in x . keys ( ) }
result = sum ( [ mu [ i ] * x [ i ] * sqrt ( M ( i ) ) for i in x . keys ( ) ] )
result /= sum ( [ x [ i ] * sqrt ( M ( i ) ) for i in x . keys ( ) ] )
return result


signature:
def render ( self , format = ReportFormat . printout ) :
    """Render the report in the specified format
 : param format : The format . The default format is to print
 the report to the console .
 : returns : If the format was set to ' string ' then a string
 representation of the report is returned ."""

implementation:
table = self . _generate_table_ ( )
if format == ReportFormat . printout :
    print ( tabulate ( table , headers = "firstrow" , tablefmt = "simple" ) )
elif format == ReportFormat . latex :
    self . _render_latex_ ( table )
elif format == ReportFormat . txt :
    self . _render_txt_ ( table )
elif format == ReportFormat . csv :
    self . _render_csv_ ( table )
elif format == ReportFormat . string :
    return str ( tabulate ( table , headers = "firstrow" , tablefmt = "simple" ) )
elif format == ReportFormat . matplotlib :
    self . _render_matplotlib_ ( )
elif format == ReportFormat . png :
    if self . output_path is None :
        self . _render_matplotlib_ ( )
    else :
        self . _render_matplotlib_ ( True )


signature:
def rgb_to_hex ( rgb ) :
    """Convert an RGB color representation to a HEX color representation .
 ( r , g , b ) : : r - > [ 0 , 255]
 g - > [ 0 , 255]
 b - > [ 0 , 255]
 : param rgb : A tuple of three numeric values corresponding to the red , green , and blue value .
 : return : HEX representation of the input RGB value .
 : rtype : str"""


signature:
def rgb_to_yiq ( rgb ) :
    """Convert an RGB color representation to a YIQ color representation .
 ( r , g , b ) : : r - > [ 0 , 255]
 g - > [ 0 , 255]
 b - > [ 0 , 255]
 : param rgb : A tuple of three numeric values corresponding to the red , green , and blue value .
 : return : YIQ representation of the input RGB value .
 : rtype : tuple"""


signature:
def rgb_to_hsv ( rgb ) :
    """Convert an RGB color representation to an HSV color representation .
 ( r , g , b ) : : r - > [ 0 , 255]
 g - > [ 0 , 255]
 b - > [ 0 , 255]
 : param rgb : A tuple of three numeric values corresponding to the red , green , and blue value .
 : return : HSV representation of the input RGB value .
 : rtype : tuple"""

implementation:
r , g , b = rgb [ 0 ] / 255 , rgb [ 1 ] / 255 , rgb [ 2 ] / 255
_min = min ( r , g , b )
_max = max ( r , g , b )
v = _max
delta = _max - _min
if _max == 0 :
    return 0 , 0 , v
s = delta / _max
if delta == 0 :
    delta = 1
if r == _max :
    h = 60 * ( ( ( g - b ) / delta ) % 6 )
elif g == _max :
    h = 60 * ( ( ( b - r ) / delta ) + 2 )
else :
    h = 60 * ( ( ( r - g ) / delta ) + 4 )
return round ( h , 3 ) , round ( s , 3 ) , round ( v , 3 )


signature:
def hex_to_rgb ( _hex ) :
    """Convert a HEX color representation to an RGB color representation .
 hex : : hex - > [ 00000 , FFFFF ]
 : param _ hex : The 3 - or 6 - char hexadecimal string representing the color value .
 : return : RGB representation of the input HEX value .
 : rtype : tuple"""


signature:
def yiq_to_rgb ( yiq ) :
    """Convert a YIQ color representation to an RGB color representation .
 ( y , i , q ) : : y - > [ 0 , 1]
 i - > [ - 0.5957 , 0.5957]
 q - > [ - 0.5226 , 0.5226]
 : param yiq : A tuple of three numeric values corresponding to the luma and chrominance .
 : return : RGB representation of the input YIQ value .
 : rtype : tuple"""


signature:
def hsv_to_rgb ( hsv ) :
    """Convert an HSV color representation to an RGB color representation .
 ( h , s , v ) : : h - > [ 0 , 360)
 s - > [ 0 , 1]
 v - > [ 0 , 1]
 : param hsv : A tuple of three numeric values corresponding to the hue , saturation , and value .
 : return : RGB representation of the input HSV value .
 : rtype : tuple"""

implementation:
h , s , v = hsv
c = v * s
h /= 60
x = c * ( 1 - abs ( ( h % 2 ) - 1 ) )
m = v - c
if h < 1 :
    res = ( c , x , 0 )
elif h < 2 :
    res = ( x , c , 0 )
elif h < 3 :
    res = ( 0 , c , x )
elif h < 4 :
    res = ( 0 , x , c )
elif h < 5 :
    res = ( x , 0 , c )
elif h < 6 :
    res = ( c , 0 , x )
else :
    raise ColorException ( "Unable to convert from HSV to RGB" )
r , g , b = res
return round ( ( r + m ) * 255 , 3 ) , round ( ( g + m ) * 255 , 3 ) , round ( ( b + m ) * 255 , 3 )


signature:
def offset_random_rgb ( seed , amount = 1 ) :
    """Given a seed color , generate a specified number of random colors ( 1 color by default ) determined by a randomized
 offset from the seed .
 : param seed :
 : param amount :
 : return :"""

implementation:
r , g , b = seed
results = [ ]
for _ in range ( amount ) :
    base_val = ( ( r + g + b ) / 3 ) + 1
    # Add one to eliminate case where the base value would otherwise be 0
    new_val = base_val + ( random . random ( ) * rgb_max_val / 5 )
    # Randomly offset with an arbitrary multiplier
    ratio = new_val / base_val
    results . append ( ( min ( int ( r * ratio ) , rgb_max_val ) , min ( int ( g * ratio ) , rgb_max_val ) , min ( int ( b * ratio ) , rgb_max_val ) ) )
return results [ 0 ] if len ( results ) > 1 else results


signature:
def color_run ( start_color , end_color , step_count , inclusive = True , to_color = True ) :
    """Given a start color , end color , and a number of steps , returns a list of colors which represent a ' scale ' between
 the start and end color .
 : param start _ color : The color starting the run
 : param end _ color : The color ending the run
 : param step _ count : The number of colors to have between the start and end color
 : param inclusive : Flag determining whether to include start and end values in run ( default True )
 : param to _ color : Flag indicating return values should be Color objects ( default True )
 : return : List of colors between the start and end color
 : rtype : list"""

implementation:
if isinstance ( start_color , Color ) :
    start_color = start_color . rgb
if isinstance ( end_color , Color ) :
    end_color = end_color . rgb
step = tuple ( ( end_color [ i ] - start_color [ i ] ) / step_count for i in range ( 3 ) )
add = lambda x , y : tuple ( sum ( z ) for z in zip ( x , y ) )
mult = lambda x , y : tuple ( y * z for z in x )
run = [ add ( start_color , mult ( step , i ) ) for i in range ( 1 , step_count ) ]
if inclusive :
    run = [ start_color ] + run + [ end_color ]
return run if not to_color else [ Color ( c ) for c in run ]


signature:
def text_color ( background , dark_color = rgb_min , light_color = rgb_max ) :
    """Given a background color in the form of an RGB 3 - tuple , returns the color the text should be ( defaulting to white
 and black ) for best readability . The light ( white ) and dark ( black ) defaults can be overridden to return preferred
 values .
 : param background :
 : param dark _ color :
 : param light _ color :
 : return :"""

implementation:
max_y = rgb_to_yiq ( rgb_max ) [ 0 ]
return light_color if rgb_to_yiq ( background ) [ 0 ] <= max_y / 2 else dark_color


signature:
def minify_hex ( _hex ) :
    """Given a HEX value , tries to reduce it from a 6 character hex ( e . g . # fffff ) to a 3 character hex ( e . g . # fff ) .
 If the HEX value is unable to be minified , returns the 6 character HEX representation .
 : param _ hex :
 : return :"""

implementation:
size = len ( _hex . strip ( '#' ) )
if size == 3 :
    return _hex
elif size == 6 :
    if _hex [ 1 ] == _hex [ 2 ] and _hex [ 3 ] == _hex [ 4 ] and _hex [ 5 ] == _hex [ 6 ] :
        return _hex [ 0 : : 2 ]
    else :
        return _hex
else :
    raise ColorException ( 'Unexpected HEX size when minifying: {}' . format ( size ) )


signature:
def get ( self , key , default = None ) :
    """Get key value , return default if key doesn ' t exist"""

implementation:
if self . in_memory :
    return self . _memory_db . get ( key , default )
else :
    db = self . _read_file ( )
    return db . get ( key , default )


signature:
def set ( self , key , value ) :
    """Set key value"""

implementation:
if self . in_memory :
    self . _memory_db [ key ] = value
else :
    db = self . _read_file ( )
    db [ key ] = value
    with open ( self . db_path , 'w' ) as f :
        f . write ( json . dumps ( db , ensure_ascii = False , indent = 2 ) )


signature:
def _read_file ( self ) :
    """read the db file content
 : rtype : dict"""

implementation:
if not os . path . exists ( self . db_path ) :
    return { }
with open ( self . db_path , 'r' ) as f :
    content = f . read ( )
    return json . loads ( content )


signature:
def attrs_sqlalchemy ( maybe_cls = None ) :
    """A class decorator that adds ` ` _ _ repr _ _ ` ` , ` ` _ _ eq _ _ ` ` , ` ` _ _ cmp _ _ ` ` , and
 ` ` _ _ hash _ _ ` ` methods according to the fields defined on the SQLAlchemy
 model class ."""

implementation:
def wrap ( cls ) :
    warnings . warn ( UserWarning ( 'attrs_sqlalchemy is deprecated' ) )
    these = { name : attr . ib ( ) # ` _ _ mapper _ _ . columns ` is a dictionary mapping field names on the
    # model class to table columns . SQLAlchemy provides many ways to
    # access the fields / columns , but this works at the time the class
    # decorator is called :
    # - We can ' t use ` cls . _ _ table _ _ . columns ` because that directly maps
    # the column names rather than the field names on the model . For
    # example , given ` _ my _ field = Column ( ' field ' , . . . ) ` ,
    # ` _ _ table _ _ . columns ` will contain ' field ' rather than ' _ my _ field ' .
    # - We can ' t use ` cls . _ _ dict _ _ ` , where values are
    # ` InstrumentedAttribute ` s , because that includes relationships ,
    # synonyms , and other features .
    # - We can ' t use ` cls . _ _ mapper _ _ . column _ attrs `
    # ( or ` sqlalchemy . inspect ` ) because they will attempt to
    # initialize mappers for all of the classes in the registry ,
    # which won ' t be ready yet .
    for name in inspect ( cls ) . columns . keys ( ) }
    return attr . s ( cls , these = these , init = False )
# ` maybe _ cls ` depends on the usage of the decorator . It ' s a class if it ' s
# used as ` @ attrs _ sqlalchemy ` but ` None ` if it ' s used as
# ` @ attrs _ sqlalchemy ( ) `
# ref : https : / / github . com / hynek / attrs / blob / 15.2.0 / src / attr / _ make . py # L195
if maybe_cls is None :
    return wrap
else :
    return wrap ( maybe_cls )


signature:
def paginate_link_tag ( item ) :
    """Create an A - HREF tag that points to another page usable in paginate ."""

implementation:
a_tag = Page . default_link_tag ( item )
if item [ 'type' ] == 'current_page' :
    return make_html_tag ( 'li' , a_tag , ** { 'class' : 'blue white-text' } )
return make_html_tag ( 'li' , a_tag )


signature:
def set_state ( _id , body ) :
    """Set a devices state ."""

implementation:
url = DEVICE_URL % _id
if "mode" in body :
    url = MODES_URL % _id
arequest = requests . put ( url , headers = HEADERS , data = json . dumps ( body ) )
status_code = str ( arequest . status_code )
if status_code != '202' :
    _LOGGER . error ( "State not accepted. " + status_code )
    return False


signature:
def get_modes ( _id ) :
    """Pull a water heater ' s modes from the API ."""

implementation:
url = MODES_URL % _id
arequest = requests . get ( url , headers = HEADERS )
status_code = str ( arequest . status_code )
if status_code == '401' :
    _LOGGER . error ( "Token expired." )
    return False
return arequest . json ( )


signature:
def get_usage ( _id ) :
    """Pull a water heater ' s usage report from the API ."""

implementation:
url = USAGE_URL % _id
arequest = requests . get ( url , headers = HEADERS )
status_code = str ( arequest . status_code )
if status_code == '401' :
    _LOGGER . error ( "Token expired." )
    return False
try :
    return arequest . json ( )
except ValueError :
    _LOGGER . info ( "Failed to get usage. Not supported by unit?" )
    return None


signature:
def get_device ( _id ) :
    """Pull a device from the API ."""

implementation:
url = DEVICE_URL % _id
arequest = requests . get ( url , headers = HEADERS )
status_code = str ( arequest . status_code )
if status_code == '401' :
    _LOGGER . error ( "Token expired." )
    return False
return arequest . json ( )


signature:
def get_locations ( ) :
    """Pull the accounts locations ."""

implementation:
arequest = requests . get ( LOCATIONS_URL , headers = HEADERS )
status_code = str ( arequest . status_code )
if status_code == '401' :
    _LOGGER . error ( "Token expired." )
    return False
return arequest . json ( )


signature:
def get_vacations ( ) :
    """Pull the accounts vacations ."""

implementation:
arequest = requests . get ( VACATIONS_URL , headers = HEADERS )
status_code = str ( arequest . status_code )
if status_code == '401' :
    _LOGGER . error ( "Token expired." )
    return False
return arequest . json ( )


signature:
def create_vacation ( body ) :
    """Create a vacation ."""

implementation:
arequest = requests . post ( VACATIONS_URL , headers = HEADERS , data = json . dumps ( body ) )
status_code = str ( arequest . status_code )
if status_code != '200' :
    _LOGGER . error ( "Failed to create vacation. " + status_code )
    _LOGGER . error ( arequest . json ( ) )
    return False
return arequest . json ( )


signature:
def delete_vacation ( _id ) :
    """Delete a vacation by ID ."""

implementation:
arequest = requests . delete ( VACATIONS_URL + "/" + _id , headers = HEADERS )
status_code = str ( arequest . status_code )
if status_code != '202' :
    _LOGGER . error ( "Failed to delete vacation. " + status_code )
    return False
return True


signature:
def _authenticate ( self ) :
    """Authenticate with the API and return an authentication token ."""

implementation:
auth_url = BASE_URL + "/auth/token"
payload = { 'username' : self . email , 'password' : self . password , 'grant_type' : 'password' }
arequest = requests . post ( auth_url , data = payload , headers = BASIC_HEADERS )
status = arequest . status_code
if status != 200 :
    _LOGGER . error ( "Authentication request failed, please check credintials. " + str ( status ) )
    return False
response = arequest . json ( )
_LOGGER . debug ( str ( response ) )
self . token = response . get ( "access_token" )
self . refresh_token = response . get ( "refresh_token" )
_auth = HEADERS . get ( "Authorization" )
_auth = _auth % self . token
HEADERS [ "Authorization" ] = _auth
_LOGGER . info ( "Authentication was successful, token set." )
return True


signature:
def get_water_heaters ( self ) :
    """Return a list of water heater devices .
 Parses the response from the locations endpoint in to a pyeconet . WaterHeater ."""

implementation:
water_heaters = [ ]
for location in self . locations :
    _location_id = location . get ( "id" )
    for device in location . get ( "equipment" ) :
        if device . get ( "type" ) == "Water Heater" :
            water_heater_modes = self . api_interface . get_modes ( device . get ( "id" ) )
            water_heater_usage = self . api_interface . get_usage ( device . get ( "id" ) )
            water_heater = self . api_interface . get_device ( device . get ( "id" ) )
            vacations = self . api_interface . get_vacations ( )
            device_vacations = [ ]
            for vacation in vacations :
                for equipment in vacation . get ( "participatingEquipment" ) :
                    if equipment . get ( "id" ) == water_heater . get ( "id" ) :
                        device_vacations . append ( EcoNetVacation ( vacation , self . api_interface ) )
            water_heaters . append ( EcoNetWaterHeater ( water_heater , water_heater_modes , water_heater_usage , _location_id , device_vacations , self . api_interface ) )
return water_heaters


signature:
def get_products ( self , latitude , longitude ) :
    """Get a list of all Uber products based on latitude and longitude coordinates .
 : param latitude : Latitude for which product list is required .
 : param longitude : Longitude for which product list is required .
 : return : JSON"""

implementation:
endpoint = 'products'
query_parameters = { 'latitude' : latitude , 'longitude' : longitude }
return self . get_json ( endpoint , 'GET' , query_parameters , None , None )


signature:
def get_price_estimate ( self , start_latitude , start_longitude , end_latitude , end_longitude ) :
    """Returns the fare estimate based on two sets of coordinates .
 : param start _ latitude : Starting latitude or latitude of pickup address .
 : param start _ longitude : Starting longitude or longitude of pickup address .
 : param end _ latitude : Ending latitude or latitude of destination address .
 : param end _ longitude : Ending longitude or longitude of destination address .
 : return : JSON"""

implementation:
endpoint = 'estimates/price'
query_parameters = { 'start_latitude' : start_latitude , 'start_longitude' : start_longitude , 'end_latitude' : end_latitude , 'end_longitude' : end_longitude }
return self . get_json ( endpoint , 'GET' , query_parameters , None , None )


signature:
def get_time_estimate ( self , start_latitude , start_longitude , customer_uuid = None , product_id = None ) :
    """Get the ETA for Uber products .
 : param start _ latitude : Starting latitude .
 : param start _ longitude : Starting longitude .
 : param customer _ uuid : ( Optional ) Customer unique ID .
 : param product _ id : ( Optional ) If ETA is needed only for a specific product type .
 : return : JSON"""

implementation:
endpoint = 'estimates/time'
query_parameters = { 'start_latitude' : start_latitude , 'start_longitude' : start_longitude }
if customer_uuid is not None :
    query_parameters [ 'customer_uuid' ] = customer_uuid
elif product_id is not None :
    query_parameters [ 'product_id' ] = product_id
elif customer_uuid is not None and product_id is not None :
    query_parameters [ 'customer_uuid' ] = customer_uuid
    query_parameters [ 'product_id' ] = product_id
return self . get_json ( endpoint , 'GET' , query_parameters , None , None )


signature:
def models_preparing ( app ) :
    """Wrap all sqlalchemy model in settings ."""

implementation:
def wrapper ( resource , parent ) :
    if isinstance ( resource , DeclarativeMeta ) :
        resource = ListResource ( resource )
    if not getattr ( resource , '__parent__' , None ) :
        resource . __parent__ = parent
    return resource
resources_preparing_factory ( app , wrapper )


signature:
def check_status ( content , response ) :
    """Check the response that is returned for known exceptions and errors .
 : param response : Response that is returned from the call .
 : raise :
 MalformedRequestException if ` response . status ` is 400
 UnauthorisedException if ` response . status ` is 401
 NotFoundException if ` response . status ` is 404
 UnacceptableContentException if ` response . status ` is 406
 InvalidRequestException if ` response . status ` is 422
 RateLimitException if ` response . status ` is 429
 ServerException if ` response . status ` > 500"""

implementation:
if response . status == 400 :
    raise MalformedRequestException ( content , response )
if response . status == 401 :
    raise UnauthorisedException ( content , response )
if response . status == 404 :
    raise NotFoundException ( content , response )
if response . status == 406 :
    raise UnacceptableContentException ( content , response )
if response . status == 422 :
    raise InvalidRequestException ( content , response )
if response . status == 429 :
    raise RateLimitException ( content , response )
if response . status >= 500 :
    raise ServerException ( content , response )


signature:
def build_request ( self , path , query_parameters ) :
    """Build the HTTP request by adding query parameters to the path .
 : param path : API endpoint / path to be used .
 : param query _ parameters : Query parameters to be added to the request .
 : return : string"""

implementation:
url = 'https://api.uber.com/v1' + self . sanitise_path ( path )
url += '?' + urlencode ( query_parameters )
return url


signature:
def get_json ( self , uri_path , http_method = 'GET' , query_parameters = None , body = None , headers = None ) :
    """Fetches the JSON returned , after making the call and checking for errors .
 : param uri _ path : Endpoint to be used to make a request .
 : param http _ method : HTTP method to be used .
 : param query _ parameters : Parameters to be added to the request .
 : param body : Optional body , if required .
 : param headers : Optional headers , if required .
 : return : JSON"""

implementation:
query_parameters = query_parameters or { }
headers = headers or { }
# Add credentials to the request
query_parameters = self . add_credentials ( query_parameters )
# Build the request uri with parameters
uri = self . build_request ( uri_path , query_parameters )
if http_method in ( 'POST' , 'PUT' , 'DELETE' ) and 'Content-Type' not in headers :
    headers [ 'Content-Type' ] = 'application/json'
headers [ 'Accept' ] = 'application/json'
response , content = self . client . request ( uri = uri , method = http_method , body = body , headers = headers )
# Check for known errors that could be returned
self . check_status ( content , response )
return json . loads ( content . decode ( 'utf-8' ) )


signature:
def _translateCommands ( commands ) :
    """Generate the binary strings for a comma seperated list of commands ."""

implementation:
for command in commands . split ( ',' ) : # each command results in 2 bytes of binary data
    result = [ 0 , 0 ]
    device , command = command . strip ( ) . upper ( ) . split ( None , 1 )
    # translate the house code
    result [ 0 ] = houseCodes [ device [ 0 ] ]
    # translate the device number if there is one
    if len ( device ) > 1 :
        deviceNumber = deviceNumbers [ device [ 1 : ] ]
        result [ 0 ] |= deviceNumber [ 0 ]
        result [ 1 ] = deviceNumber [ 1 ]
    # translate the command
    result [ 1 ] |= commandCodes [ command ]
    # convert 2 bytes to bit strings and yield them
    yield ' ' . join ( map ( _strBinary , result ) )


signature:
def _strBinary ( n ) :
    """Conert an integer to binary ( i . e . , a string of 1s and 0s ) ."""

implementation:
results = [ ]
for i in range ( 8 ) :
    n , r = divmod ( n , 2 )
    results . append ( '01' [ r ] )
results . reverse ( )
return '' . join ( results )


signature:
def _sendBinaryData ( port , data ) :
    """Send a string of binary data to the FireCracker with proper timing .
 See the diagram in the spec referenced above for timing information .
 The module level variables leadInOutDelay and bitDelay represent how
 long each type of delay should be in seconds . They may require tweaking
 on some setups ."""

implementation:
_reset ( port )
time . sleep ( leadInOutDelay )
for digit in data :
    _sendBit ( port , digit )
time . sleep ( leadInOutDelay )


signature:
def _sendBit ( port , bit ) :
    """Send an individual bit to the FireCracker module usr RTS / DTR ."""

implementation:
if bit == '0' :
    _setRTSDTR ( port , 0 , 1 )
elif bit == '1' :
    _setRTSDTR ( port , 1 , 0 )
else :
    return
time . sleep ( bitDelay )
_setRTSDTR ( port , 1 , 1 )
time . sleep ( bitDelay )


signature:
def _setRTSDTR ( port , RTS , DTR ) :
    """Set RTS and DTR to the requested state ."""

implementation:
port . setRTS ( RTS )
port . setDTR ( DTR )