Introducing an input variable

The syntax to introduce an input variable is very similar to the one we used to code a formula.

For instance:

class salary(Variable):
    value_type = float
    entity = Person
    label = u"Salary earned by a person for a given month"
    definition_period = MONTH

The only difference is that we do not have a formula to calculate the value of a variable.

If we ask the value of salary for a given month, the returned result will be:

  • The input that was provided when initializing the simulation if it exists.

  • The default value of the Variable if no input has been provided.

Setting a default value

When declaring an input variable, you can change its default value by adding the default_value attribute:

class french_citizen(Variable):
    value_type = bool
    default_value = True
    entity = Person
    label = u"Whether the person is a French citizen"
    definition_period = YEAR

If you do not explicitly define a default value, the following will be used:

  • For numeric variables: 0.

  • For boolean variables: False.

Advanced example: enumerations (enum)

Usecases

Enumerations are variables that have a limited set of possible values. For instance:

  • Highest academic level: high school, associate degree, bachelor’s degree, master’s degree, doctorate…

  • A household housing occupancy status: owner, tenant, free-lodger, homeless…

  • The main occupation of a person: employee, freelancer, retired, student, unemployed…

Defining and using an enumeration variable

As an example, let’s code a housing_tax that is paid by households who own or rent their main homes, but does not apply to households that do not have a stable residence, or are accommodated for free.

The variable housing_tax will thus depend on housing_occupancy_status, an enumeration variable that can take 4 values: tenant, owner, free_lodger and homeless.

First, we can create an enumerated type HousingOccupancyStatus:

class HousingOccupancyStatus(Enum):
    tenant = u'Tenant or lodger who pays a rent'
    owner = u'Owner'
    free_lodger = u'Free logder'
    homeless = u'Homeless'

OpenFisca enums are based on Python 3 native enums. Each enum item (for instance HousingOccupancyStatus.tenant) has:

  • a name attribute that contains its key (e.g. tenant)

  • a value attribute that contains its description (e.g. "Tenant or lodger who pays a monthly rent")

Then, create an OpenFisca variable housing_occupancy_status:

class housing_occupancy_status(Variable):
    value_type = Enum
    possible_values = HousingOccupancyStatus
    default_value = HousingOccupancyStatus.tenant  # The default is mandatory
    entity = Household
    definition_period = MONTH
    label = u"Legal housing situation of the household concerning their main residence"

You can now use the enum in variable formulas!

For instance, assuming the enumeration and the formula using it are defined in the same file:

class housing_tax(Variable):
    value_type = float
    entity = Household
    definition_period = MONTH.
    label = u"Tax paid by each household proportionnally to the size of its accommodation"

    def formula(household, period, legislation):
        accommodation_size = household('accomodation_size', period)
        housing_occupancy_status = household('housing_occupancy_status', period)
        tenant = (housing_occupancy_status == HousingOccupancyStatus.tenant)
        owner = (housing_occupancy_status == HousingOccupancyStatus.owner)

        # The tax is applied only if the household owns or rents its main residency
        return (owner + tenant) * accommodation_size * 10

If the enumeration and the formula using it are not defined in the same file, an extra step is necessary:

class housing_tax(Variable):
    value_type = float
    entity = Household
    definition_period = MONTH.
    label = u"Tax paid by each household proportionnally to the size of its accommodation"

    def formula(household, period, legislation):
        accommodation_size = household('accomodation_size', period)
        housing_occupancy_status = household('housing_occupancy_status', period)
        HousingOccupancyStatus = housing_occupancy_status.possible_values  # "Import" the enum type. Careful: do not use python imports accross variables files: comparisons would not work!
        tenant = (housing_occupancy_status == HousingOccupancyStatus.tenant)
        owner = (housing_occupancy_status == HousingOccupancyStatus.owner)

        # The tax is applied only if the household owns or rents its main residency
        return (owner + tenant) * accommodation_size * 10

You can now test the formula in a YAML test:

- name: Household with free lodger status living in a 100 sq.meters accomodation
  period: 2017
  input:
    accomodation_size:
      2017-01: 100
    housing_occupancy_status:
      2017-01: free_lodger
  output:
    housing_tax: 0