モデル

oTree アプリには 3 つのデータモデル「サブセッション(Subsession)、グループ(Group)、プレイヤー(Player)」があります。

プレイヤーはグループの一部であり、グループはサブセッションの一部です。詳しくは コンセプト を参照してください。

例えば、次のようなデータを生成する実験を考えてみましょう:

name    age is_student
John    30  False
Alice   22  True
Bob     35  False
...

上記のテーブル構造を定義する方法は以下の通りです:

class Player(BasePlayer):
    name = models.StringField()
    age = models.IntegerField()
    is_student = models.BooleanField()

つまり、 モデル とは基本的にデータベースのテーブルです。そして、 フィールド とはテーブルの列のことです。

フィールド

フィールドタイプ

  • BooleanField (true/false や yes/no の値用)
  • CurrencyField (通貨額用); 詳しくは 通貨 (Currency) を参照
  • IntegerField
  • FloatField (実数用)
  • StringField (文字列用)
  • LongStringField (長い文字列用; このフィールドのフォームウィジェットは複数行のテキストエリアになります)

初期値 / デフォルト値

initial= で設定しない限り、フィールドの初期値は None になります:

class Player(BasePlayer):
    some_number = models.IntegerField(initial=0)

最小値、最大値、選択肢

フィールドの最小値 (min), 最大値 (max), 選択肢 (choices) を設定する方法は シンプルなフォームの検証 を参照してください。

組み込みのフィールドとメソッド

プレイヤー、グループ、サブセッションには、いくつかの定義済みフィールドがあります。たとえば、 Player には payoffid_in_group というフィールドがあり、 in_all_rounds()get_others_in_group() などのメソッドがあります。

これらの組み込みフィールドとメソッドを以下に示します。

Subsession

round_number

現在のラウンド数を返します。アプリが複数のラウンドを持っている場合 (C.NUM_ROUNDS で設定) にのみ関係します。詳しくは ラウンド を参照してください。

get_groups()

サブセッション内のすべてのグループをリストで返します。

get_players()

サブセッション内のすべてのプレイヤーをリストで返します。

Player

id_in_group

自動的に割り当てられる1から始まる整数。マルチプレイヤーゲームでは、このフィールドがプレイヤー1なのか、プレイヤー2なのか、などを示す。

payoff

このラウンドでのプレイヤーの利得。詳しくは 利得 (payoff) を参照。

round_number

現在のラウンド数を返します。

Session

num_participants

セッションの参加者数

vars

session fields を参照

Participant

id_in_session

セッション内の参加者のID。このフィールドは、プレイヤーの id_in_subsession と同じです。

その他の参加者の属性とメソッド

Constants

C は、アプリのパラメータやプレイヤーごとに変化することがない定数を定義するために推奨される場所です。

組み込みの定数を以下に示します:

アプリの実名を URL に表示したくない場合は、文字列定数 NAME_IN_URL に任意の名前を定義します。

定数には、数字、文字列、ブーリアン、リストなどを定義できます。しかし、辞書型や辞書型のリストなど、より複雑なデータタイプの場合は、代わりに関数の中で定義する必要があります。例えば、 my_dict という定数を定義する代わりに、次のようにします:

def my_dict(subsession):
    return dict(a=[1,2], b=[3,4])

その他のトピック

random() の使用について

関数の外で乱数を生成してはいけません。例えば、以下のようなことはしないでください:

class C(BaseConstants):
    P = random.randint(1, 10) # wrong

ランダムに変化するなら、それは定数ではありません。

以下のようなこともしないでください:

class Player(BasePlayer):

    p = models.FloatField(
        # wrong
        initial=random.randint(1, 10)
    )

これらは、サーバーが新しいプロセスを起動するたびに変更されるため、動作しません。テスト中はうまくいっているように見えても、実際は壊れてしまいます。代わりに、 処理の割り当て のような関数の中でランダムな変数を生成するべきです。(ユーザーがページを更新すると再実行されてしまう vars_for_template では好ましくありません。)