models.py
是您定义应用程序数据模型的位置:
Player是Group的一部分,这是Subsession的一部分。请参阅概念概述。
主要目的models.py
是定义数据库表的列。假设您希望实验生成如下所示的数据:
以下是如何定义上面的表结构:
以下是主要的字段类型:
BooleanField
(对于true / false和yes / no值)
CurrencyField
货币金额; 看货币和支付。IntegerField
FloatField
(对于实数)StringField
(用于文本字符串)LongStringField
(对于长文本字符串;其表单小部件是多行textarea)StringField
并且LongStringField
是新的(2018年1月添加)。有关更多信息,请参阅oTree 2.0。
您的字段的初始值将是None
,除非您设置initial=
:
有关如何设置一个字段的信息min
,max
或choices
见简单的表单字段验证。
定义的字段和方法。例如,Player
表中有一个名为列payoff
和id_in_group
,以及类似的方法in_all_rounds()
和get_others_in_group()
。
下面列出了这些内置字段和方法。
session
本次会话所属的会话。看什么是self
round_number
给出当前的轮数。仅当应用程序有多轮(设置Constants.num_rounds
)时才相关。见Rounds。
creating_session()
与大多数其他内置子会话方法不同,此方法是您必须自己定义的方法。您在此处放置的任何代码都在创建会话时执行:
creating_session
允许您通过在玩家,组,参与者或子会话的字段上设置初始值来初始化子级别。例如:
有关 treatments 和 group shuffling.更多信息。
请注意,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
请参见session.vars。
vars
参见participant.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中描述)
您可以在模型上定义自己的方法。这可以帮助您在代码变得更复杂时保持代码的有序性。例如,您可以定义一个功能来设置玩家的收益:
只需记住从某个地方调用此函数,例如您的页面:
因为它不会被自动执行,不像如内置的功能creating_session()
,after_all_players_arrive()
等等。
任何不在方法内的代码基本上都是全局的,并且只会执行一次 - 当服务器启动时。
有些人错误地认为代码会为每个新会话重新执行。例如,想要生成硬币翻转的随机概率的人可能会在models.py中执行此操作:
从打印输出中可以看出,p
只计算一次:服务器启动时:
这意味着所有会议的所有参与者都是一样的。
出于同样的原因,这也不起作用:
解决方案是在方法内生成随机变量,例如creating_session()。
在你的代码,你应该总是使用小写player
, group
和subsession
。唯一的例外是在models.py中定义类,您使用class Player(BasePlayer)
的等等。
我们Player
在引用整个玩家表时使用大写(例如),player
在引用特定玩家时使用小写(),即表中的一行。在Python中,Player
是一个类,并且player
是该类的实例。
例如,在模板中,为了显示玩家的收益,我们必须使用{{ player.payoff }}
,而不是{{ Player.payoff }}
。
但是,因为Constants
,我们总是使用大写。那是因为Constants
不是带有实例/行的数据库表,因为所有玩家的常量都是相同的。
IntegerField
是数据库表中的一列。Integer是该表中的一个值。
假设您的应用有许多几乎相同的字段,例如:
这很复杂; 你应该寻找一种简化方法。
这些字段是否都显示在不同的页面上?如果是这样,请考虑将其转换为仅有一个字段的10轮游戏。请参阅 真实努力 示例游戏,了解如何让1个页面循环多轮,改变每轮显示的问题。
如果那是不可能的,那么你可以通过定义一个返回字段的函数来减少重复代码的数量(make_field
这只是一个示例名称;你可以调用任何东西)。