Skip to the content.

OpenFisca-Japanのチュートリアル

架空の「3の倍数給付金💴」の実装を通して、OpenFisca-Japanの開発方法について理解を深めましょう!

目的

前提

架空の制度「3の倍数給付金💴」


では、これから下記のような段階を踏んで「3の倍数給付金💴」の制度を実装していきましょう!

STEP1:テストデータを作成する

OpenFiscaの概念やテストyamlファイルについて

テストデータを作成する前に、OpenFiscaの概念やテストデータのyamlファイルの形式について説明します。

テストデータのYAMLファイルを作成

  1. tests/チュートリアル/3の倍数給付金.yamlの空ファイルを作成します。
  2. 下記の「親1のみが給付対象の場合」を参考にして、テストケースを記載して保存します。

     - name: 親1のみが給付対象の場合 # テストケース名
       period: 2023-01-01 # テストで対象とする日・期間(日によって金額が変わることを確認する時などに使用する)
       input: # 入力情報(entities.pyやvariables/xxx.pyに定義されている項目を記載できる)
         世帯:
           親一覧:
             - 親1
             - 親2
           祖父母一覧:
             - 祖父母1
             - 祖父母2
           子一覧:
             - 子1
             - 子2
         世帯員:
           親1:
             年齢: 45
           親2:
             年齢: 44
           祖父母1:
             年齢: 74
           祖父母2:
             年齢: 74
           子1:
             年齢: 19
           子2:
             年齢: 2
       output:
         世帯:
           三の倍数給付金: 100000
    
CLICK:全てのテストデータを見る
- name: 親1のみが給付対象の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 45
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 19
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 100000

- name: 親1のみが給付対象で他の世帯員がいない場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
    世帯員:
      親1:
        年齢: 45
  output:
    世帯:
      三の倍数給付金: 100000

- name: 親2のみが給付対象の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 45
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 19
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 100000

- name: 祖父母1のみが給付対象の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 75
      祖父母2:
        年齢: 74
      子1:
        年齢: 19
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 100000

- name: 祖父母2のみが給付対象の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 75
      子1:
        年齢: 19
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 100000

- name: 子1のみが給付対象の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 21
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 100000

- name: 子2のみが給付対象の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 19
      子2:
        年齢: 3
  output:
    世帯:
      三の倍数給付金: 100000

- name: 子1のみが給付対象でボーナス対象(小学校3年生)の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 9
        学年: 3 # 小学校3年生
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 130000

- name: 子1のみが給付対象でボーナス対象(小学校6年生)の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 12
        学年: 6 # 小学校6年生
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 130000

- name: 子1のみが給付対象でボーナス対象(中学校3年生)の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 15
        学年: 9 # 中学校3年生
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 130000

- name: 子1のみが給付対象でボーナス対象(高校3年生)の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 18
        学年: 12 # 高校3年生
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 130000

- name: 全員が給付対象である場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 45
      親2:
        年齢: 45
      祖父母1:
        年齢: 75
      祖父母2:
        年齢: 75
      子1:
        年齢: 21
      子2:
        年齢: 3
  output:
    世帯:
      三の倍数給付金: 600000

- name: 全員が給付対象で子供が全員ボーナス対象の場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 45
      親2:
        年齢: 45
      祖父母1:
        年齢: 75
      祖父母2:
        年齢: 75
      子1:
        年齢: 18
        学年: 12 # 高校3年生
      子2:
        年齢: 9
        学年: 3 # 小学校3年生
# 小学校3年生
  output:
    世帯:
      三の倍数給付金: 660000

- name: 給付対象の世帯員がいない場合
  period: 2023-01-01
  input:
    世帯:
      親一覧:
        - 親1
        - 親2
      祖父母一覧:
        - 祖父母1
        - 祖父母2
      子一覧:
        - 子1
        - 子2
    世帯員:
      親1:
        年齢: 44
      親2:
        年齢: 44
      祖父母1:
        年齢: 74
      祖父母2:
        年齢: 74
      子1:
        年齢: 19
      子2:
        年齢: 2
  output:
    世帯:
      三の倍数給付金: 0

STEP2:”年齢が3の倍数の世帯員の1人につき、年間10万円を給付する”を実装する

1. 3の倍数給付金のPythonファイルを作成する

  1. variables/チュートリアル/3の倍数給付金.py のファイルを作成する
    • 内容は下記を参考にする
     """
     3の倍数給付金の実装
     """
    
     import numpy as np
    
     from openfisca_core.periods import DAY
     from openfisca_core.variables import Variable
     from openfisca_japan.entities import 世帯
     from openfisca_japan.variables.全般 import 小学生学年, 中学生学年, 高校生学年
    
     # 数字始まりのクラス名を使えないので、漢数字を使っている
     class 三の倍数給付金(Variable):
         value_type = int # この給付金は小数にはならないので整数型のintを指定している
         entity = 世帯 # この給付金は世帯ごとに支給されるので世帯を指定している
         definition_period = DAY # この給付金は年額で給付されるため本来はYEARが適切。しかし、現状では他のVariableがDAYになっているなどの理由でDAYにしないと動かない。設計の見直しが必要。
         label = "年齢が3の倍数の世帯員の1人につき、年間10万円を給付する架空の制度。一部の学生については追加で年間3万円を給付する。" # このVariableの説明
         reference = "https://project-inclusive.github.io/OpenFisca-Japan/tutorial.html" # この給付金の情報が掲載されているサイトのURL
    
         def formula(対象世帯, 対象期間, parameters): # この給付金の計算式を記述する
             # 世帯員の年齢を取得する
             # == 処理を記載する ==
                
             # 各世帯員が3の倍数の年齢であるかを判定する
             # == 処理を記載する ==
                
             # 判定結果から世帯の給付金額の合計値を算出する
             # == 処理を記載する ==
    
             return 給付金額
    

2. 給付金額のパラメーターファイルを作成する

各制度の時期によって変わる可能性がある値(金額など)はパラメーターファイルとして管理します。

  1. 下記の内容でparameters/チュートリアル/三の倍数給付金額_通常.yaml のファイルを作成する

     description: 3の倍数給付金額_通常
     metadata:
       reference: https://project-inclusive.github.io/OpenFisca-Japan/tutorial.html
       unit: currency-JPY
     values:
       2023-01-01:
         value: 100000
    

3. 処理を記載する

  1. == 処理を記載する == となっている部分にコードを記載する
CLICK:記載後の内容を見る
    def formula(対象世帯, 対象期間, parameters): # この給付金の計算式を記述する
        # 世帯員の年齢を取得する
        世帯員の年齢一覧 = 対象世帯.members("年齢", 対象期間)
        
        # 各世帯員が3の倍数の年齢であるかを判定する
        年齢が3の倍数である = 世帯員の年齢一覧 % 3 == 0   # 条件に該当するか否かのbool値のndarray配列ができる
        
        # 判定結果から世帯の給付金額の合計値を算出する
        給付金額一覧 = 年齢が3の倍数である * parameters(対象期間).チュートリアル.三の倍数給付金額_通常   #  世帯員ごとに給付される額が格納されたndarray配列ができる
        給付金額 = 対象世帯.sum(給付金額一覧)   # numpy の関数はできるだけ使わないことが望ましい

        # デバッグ用(エラーが発生したら出力される)
        print('======== START ========')
        print('世帯員の年齢一覧', 世帯員の年齢一覧)
        print('年齢が3の倍数である', 年齢が3の倍数である)
        print('給付金額一覧', 給付金額一覧)
        print('給付金額', 給付金額)
        print('======== END ========')

        # エラーが発生した場合に標準出力が表示されるため、デバッグのために強制的にエラーを発生させることも有用
        # (出力結果とテストに記載の結果が一致せずテストに失敗するだけでは標準出力は表示されない)
        # raise ValueError("debug")  

        return 給付金額

3. テストを実行する

  1. OpenFiscaのdockerコンテナに入る
    • ※前提にも記載のとおり、docker composeでOpenFiscaコンテナが起動している必要があります。
     docker compose exec openfisca /bin/bash
    
  2. OpenFiscaのファイルをbuildする
    • variables/配下のファイルを変更するたびにmake buildが必要となります。
     make build
    
  3. テストを実行する
    • ボーナス対象のテストが失敗するので、ボーナス対象を考慮した処理を追加しましょう
     openfisca test --country-package openfisca_japan openfisca_japan/tests/チュートリアル/3の倍数給付金.yaml
    

STEP3:”小学校3年生、小学校6年生、中学校3年生、高校3年生”に対するロジックを追加する

1. ボーナス金額のパラメーターファイルを作成する

  1. 下記の内容でparameters/チュートリアル/三の倍数給付金額_ボーナス.yaml のファイルを作成する

     description: 3の倍数給付金額_ボーナス
     metadata:
       reference: https://project-inclusive.github.io/OpenFisca-Japan/tutorial.html
       unit: currency-JPY
     values:
       2023-01-01:
         value: 30000
    

2. ボーナス対象の処理を追加する

  1. == 処理を記載する == となっている部分にコードを記載する

         def formula(対象世帯, 対象期間, parameters): # この給付金の計算式を記述する
             # 世帯員の年齢を取得する
             世帯員の年齢一覧 = 対象世帯.members("年齢", 対象期間)
                
             # 各世帯員が3の倍数の年齢であるかを判定する
             年齢が3の倍数である = 世帯員の年齢一覧 % 3 == 0   # 条件に該当するか否かのbool値のndarray配列ができる
    
             # 世帯員の学年を取得する
             # == 処理を記載する ==
    
             # 各世帯員がボーナス対象学年であるかを判定する
             # == 処理を記載する ==
                
             # 判定結果から世帯の給付金額の合計値を算出する
             # == 処理を記載する ==
    
             return 給付金額  
    
CLICK:記載後の内容を見る
    def formula(対象世帯, 対象期間, parameters): # この給付金の計算式を記述する
        # 世帯員の年齢を取得する
        世帯員の年齢一覧 = 対象世帯.members("年齢", 対象期間)
        
        # 各世帯員が3の倍数の年齢であるかを判定する
        年齢が3の倍数である = 世帯員の年齢一覧 % 3 == 0   # 条件に該当するか否かのbool値のndarray配列ができる

        # 世帯員の学年を取得する
        世帯員の学年一覧 = 対象世帯.members("学年", 対象期間)

        # 各世帯員がボーナス対象学年であるかを判定する
        # == 処理を記載する ==
        小学三年生である = 世帯員の学年一覧 == 小学生学年.三年生.value  # 条件に該当するか否かのbool値のndarray配列ができる
        小学六年生である = 世帯員の学年一覧 == 小学生学年.六年生.value
        中学三年生である = 世帯員の学年一覧 == 中学生学年.三年生.value
        高校三年生である = 世帯員の学年一覧 == 高校生学年.三年生.value
        ボーナス対象学年である = 小学三年生である + 小学六年生である + 中学三年生である + 高校三年生である  # OpenFiscaでは or の代わりに + を用います

        # 判定結果から世帯の給付金額の合計値を算出する
        給付金額一覧 = 年齢が3の倍数である * parameters(対象期間).チュートリアル.三の倍数給付金額_通常 + ボーナス対象学年である * parameters(対象期間).チュートリアル.三の倍数給付金額_ボーナス  #  世帯員ごとに給付される額が格納されたndarray配列ができる
        給付金額 = 対象世帯.sum(給付金額一覧)   # numpy の関数はできるだけ使わないことが望ましい

        # デバッグ用(エラーが発生したら出力される)
        print('======== START ========')
        print('世帯員の年齢一覧', 世帯員の年齢一覧)
        print('年齢が3の倍数である', 年齢が3の倍数である)
        print('世帯員の学年一覧', 世帯員の学年一覧)
        print('ボーナス対象学年である', ボーナス対象学年である)
        print('給付金額一覧', 給付金額一覧)
        print('給付金額', 給付金額)
        print('======== END ========')

        # エラーが発生した場合に標準出力が表示されるため、デバッグのために強制的にエラーを発生させることも有用
        # (出力結果とテストに記載の結果が一致せずテストに失敗するだけでは標準出力は表示されない)
        # raise ValueError("debug")  

        return 給付金額

2. テストを実行する

  1. 先程と同じようにbuildしてからテストを実行しましょう
    • 成功したことを確認できたら終わりです
    • (複雑な制度の場合は段階的に実装→テストを繰り返していく方が一気に実装するよりも進めやすいと思います!)
     make build
    
     openfisca test --country-package openfisca_japan openfisca_japan/tests/チュートリアル/3の倍数給付金.yaml
    

STEP4:Web APIとしてデータを取得してみる

  1. dockerコンテナを抜けて、OpenFiscaコンテナを再起動します
    • これをしないと既に起動しているAPIに3の倍数給付金のコード変更が反映されないためです
     exit # コンテナを抜ける
    
     docker compose restart openfisca
    
  2. http://localhost:8080 で起動しているSwagger-UIを開きます
  3. POST/calculateを展開し、「Try it out」をクリックします
  4. Request Bodyに下記のJSONを記載し、Executeをクリックします
      {
       "世帯員": {
           "あなた": {
               "誕生年月日": {
                   "ETERNITY": "1978-01-01"
               }
           },
           "配偶者": {
               "誕生年月日": {
                   "ETERNITY": "1979-01-01"
               }
           },
           "子1": {
               "誕生年月日": {
                   "ETERNITY": "2005-01-01"
               }
           }
       },
       "世帯一覧": {
           "世帯1": {
               "親一覧": [
                   "あなた",
                   "配偶者"
               ],
               "子一覧": [
                   "子1"
               ],
               "三の倍数給付金": {
                   "2023-01-01": null
               }
           }
       }
     }
    
  5. Responseで三の倍数給付金に金額が設定されていることを確認します

以上です。

ぜひ、OpenFisca-Japanの開発に気軽に参加してみてください!

また、本チュートリアルの内容に関しても気になる点があればIssue化して修正していただいて構いません!

各コントリビューターの力でより良い内容にしていきましょう!