1. 程式人生 > >oTree學習教程(二)Models

oTree學習教程(二)Models

Models

models.py 是您定義應用程式資料模型的位置:

  • Subsession
  • Group
  • Player

PlayerGroup的一部分,這是Subsession的一部分。請參閱概念概述

主要目的models.py是定義資料庫表的列。假設您希望實驗生成如下所示的資料:

以下是如何定義上面的表結構:

Defining a column(定義列)

欄位型別

以下是主要的欄位型別:

  • BooleanField (對於true / false和yes / no值)

  • CurrencyField貨幣金額; 看貨幣和支付
  • IntegerField
  • FloatField
     (對於實數)
  • StringField (用於文字字串)
  • LongStringField (對於長文字字串;其表單小部件是多行textarea)

StringField並且LongStringField是新的(2018年1月新增)。有關更多資訊,請參閱oTree 2.0

初始/預設值

您的欄位的初始值將是None,除非您設定initial=

最小,最大,選擇

有關如何設定一個欄位的資訊minmaxchoices簡單的表單欄位驗證

Built-in fields and methods(內建欄位和方法)

定義的欄位和方法。例如,Player表中有一個名為列payoff

 和id_in_group,以及類似的方法in_all_rounds()get_others_in_group()

下面列出了這些內建欄位和方法。

Subsession

session

本次會話所屬的會話。看什麼是self

round_number 

給出當前的輪數。僅當應用程式有多輪(設定Constants.num_rounds)時才相關。見Rounds。

creating_session()

與大多數其他內建子會話方法不同,此方法是您必須自己定義的方法。您在此處放置的任何程式碼都在建立會話時執行:

creating_session允許您通過在玩家,組,參與者或子會話的欄位上設定初始值來初始化子級別。例如:

請注意,self這是一個subsession物件,因為我們在Subsession類中。所以,你做不到self.player,因為在subsession中有超過1名玩家。相反,self.get_players()用來獲取所有這些。

如果您的應用有多輪,則creating_session連續多次執行:

將輸出

before_session_starts 

before_session_starts已重新命名為creating_session()。但是,before_session_starts為了向後相容,仍然會執行新版本的oTree 。

group_randomly()

請參閱組匹配

group_like_round()

請參閱組匹配

get_group_matrix()

請參閱組匹配

set_group_matrix()

請參閱組匹配

get_groups()

返回subsession中所有組的列表。

get_players()

返回subsession中所有玩家的列表。

in_previous_rounds()

in_all_rounds()

in_round(round_number)

in_rounds(self,first,last)

會議/子會話

此組所屬的會話/子會話。看什麼是“自我”?

get_players()

請參閱

get_player_by_role(角色)

請參閱

get_player_by_id(id_in_group)

請參閱

set_players(players_list)

請參閱組匹配

in_previous_rounds()

in_all_rounds()

in_round(round_number)

in_rounds(self,first,last)

玩家

id_in_group 

從1開始自動分配整數。在多人遊戲中,指示這是播放器1,播放器2等。

支付

玩家在這輪中的回報。看到收益

會話/子會話/組/參與者

此玩家所屬的會話/子會/群組/參與者。看什麼是“自我”?

get_others_in_group()

請參閱

get_others_in_subsession()

請參閱

角色()

與大多數其他內建玩家方法不同,這是您自己定義的方法。

此函式應返回帶有玩家角色的標籤,通常取決於id_in_group

例如:

然後你可以get_player_by_role('seller')用來獲得玩家2.見

此外,玩家的角色將顯示在oTree管理介面的“結果”選項卡中。

in_previous_rounds()

in_all_rounds()

in_round(round_number)

in_rounds(self,first,last)

會話

NUM_PARTICIPANTS 

會議參加人數。

配置

vars

參加者

vars

標籤

請參閱參與者標籤

id_in_session 

會話中的參與者ID。這與玩家的相同 id_in_subsession

支付

看到收益

payoff_plus_participation_fee()

看到收益

常數

Constants建議使用該類來放置應用程式的引數和常量,這些引數和常量不會因玩家而異。

以下是必需的常量:

  • name_in_url:用於在參與者的URL中標識您的應用的名稱。

    例如,如果將其設定為public_goods,參與者的URL可能如下所示:

    http://otree-demo.herokuapp.com/p/zuzepona/public_goods/Introduction/1/

  • players_per_group(在小組中描述)

  • num_rounds(在Rounds中描述)

Miscellaneous topics(雜項)

定義自己的方法

您可以在模型上定義自己的方法。這可以幫助您在程式碼變得更復雜時保持程式碼的有序性。例如,您可以定義一個功能來設定玩家的收益:

只需記住從某個地方呼叫此函式,例如您的頁面:

因為它不會被自動執行,不像如內建的功能creating_session()after_all_players_arrive()等等。

oTree如何執行程式碼

任何不在方法內的程式碼基本上都是全域性的,並且只會執行一次 - 當伺服器啟動時。

有些人錯誤地認為程式碼會為每個新會話重新執行。例如,想要生成硬幣翻轉的隨機概率的人可能會在models.py中執行此操作:

從列印輸出中可以看出,p只計算一次:伺服器啟動時:

這意味著所有會議的所有參與者都是一樣的。

出於同樣的原因,這也不起作用:

“玩家”和“玩家”之間有什麼區別?

在你的程式碼,你應該總是使用小寫player, groupsubsession。唯一的例外是在models.py中定義類,您使用class Player(BasePlayer)的等等。

我們Player在引用整個玩家表時使用大寫(例如),player在引用特定玩家時使用小寫(),即表中的一行。在Python中,Player是一個類,並且player 是該類的例項。

例如,在模板中,為了顯示玩家的收益,我們必須使用{{ player.payoff }},而不是{{ Player.payoff }}

但是,因為Constants,我們總是使用大寫。那是因為Constants不是帶有例項/行的資料庫表,因為所有玩家的常量都是相同的。

IntegerField和Integer有什麼區別?

IntegerField是資料庫表中的一列。Integer是該表中的一個值。

如何製作多個欄位

假設您的應用有許多幾乎相同的欄位,例如:

這很複雜; 你應該尋找一種簡化方法。

這些欄位是否都顯示在不同的頁面上?如果是這樣,請考慮將其轉換為僅有一個欄位的10輪遊戲。請參閱 真實努力 示例遊戲,瞭解如何讓1個頁面迴圈多輪,改變每輪顯示的問題。

如果那是不可能的,那麼你可以通過定義一個返回欄位的函式來減少重複程式碼的數量(make_field這只是一個示例名稱;你可以呼叫任何東西)。

​​​​​​​