oTree Forum >

AttributeError: 'Player' object has no attribute 'player'

#1 by Rita

Hello,everyone,I want to do a market experiment using oTree, where buyers and sellers are paired to make decisions about the quality and price of goods and whether to purchase them. But i meet this problem and my codes are as follows. I will appreciate it if someone can help me.
Exception in ASGI application
Traceback (most recent call last):
  File "D:\Python\python3.11.3\Lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 396, in run_asgi
    result = await app(self.scope, self.receive, self.send)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\middleware\base.py", line 26, in __call__
    await response(scope, receive, send)
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\responses.py", line 224, in __call__
    await run_until_first_complete(
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\concurrency.py", line 24, in run_until_first_complete
    [task.result() for task in done]
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\concurrency.py", line 24, in <listcomp>
    [task.result() for task in done]
     ^^^^^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\responses.py", line 216, in stream_response
    async for chunk in self.body_iterator:
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\middleware\base.py", line 56, in body_stream
    task.result()
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\middleware\base.py", line 38, in coro
    await self.app(scope, receive, send)
  File "D:\Python\python3.11.3\Lib\site-packages\otree\errorpage.py", line 247, in __call__
    raise exc  # from None
    ^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\otree\errorpage.py", line 227, in __call__
    await self.app(scope, receive, _send)
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\middleware\base.py", line 25, in __call__
    response = await self.dispatch_func(request, self.call_next)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\otree\middleware.py", line 42, in dispatch
    response = await call_next(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\middleware\base.py", line 45, in call_next
    task.result()
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\middleware\base.py", line 38, in coro
    await self.app(scope, receive, send)
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\middleware\sessions.py", line 75, in __call__
    await self.app(scope, receive, send_wrapper)
  File "D:\Python\python3.11.3\Lib\site-packages\otree\patch.py", line 41, in __call__
    raise exc  # from None
    ^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\otree\patch.py", line 29, in __call__
    await self.app(scope, receive, sender)
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\routing.py", line 582, in __call__
    await route.handle(scope, receive, send)
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\routing.py", line 243, in handle
    await self.app(scope, receive, send)
  File "D:\Python\python3.11.3\Lib\site-packages\otree\views\abstract.py", line 118, in dispatch
    response = await run_in_threadpool(self.inner_dispatch, request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\starlette\concurrency.py", line 40, in run_in_threadpool
    return await loop.run_in_executor(None, func, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python\python3.11.3\Lib\site-packages\otree\database.py", line 586, in __getattribute__
    res = super().__getattribute__(attr)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Player' object has no attribute 'player'




from otree.api import *
from django.db import models as djmodels

# 定义实验的常量
class Constants(BaseConstants):
    name_in_url = 'market_experiment'
    players_per_group = None
    num_rounds = 1
    num_buyers = 10
    num_sellers = 10

# 定义子实验
class Subsession(BaseSubsession):
    def creating_session(self):
        # 确保有足够的玩家来形成买家和卖家的配对
        players = self.get_players()
        if len(players) < Constants.num_buyers + Constants.num_sellers:
            raise ValueError("Not enough players to form buyer and seller pairs.")

        # 将玩家分为卖家和买家
        sellers = [p for p in players if 'F' in p.player_role]
        buyers = [p for p in players if 'C' in p.player_role]

        # 为每个卖家和买家分配配对
        for i in range(min(len(sellers), len(buyers))):
            seller = sellers[i]
            buyer = buyers[i]
            seller.partner_id = buyer.id
            buyer.partner_id = seller.id
            print(f"Seller {seller.id_in_group} role: {seller.player_role}, partner: {buyer.id_in_group}")
            print(f"Buyer {buyer.id_in_group} role: {buyer.player_role}, partner: {seller.id_in_group}")

# 定义组
class Group(BaseGroup):
    pass

# 定义玩家模型
class Player(BasePlayer):
    # 玩家属性
    player_role = models.StringField()
    partner_id = models.IntegerField(null=True)
    quality = models.IntegerField(
        label="商品的品质:",
        min=0, max=100
    )
    price = models.CurrencyField(
        label="商品的价格:",
        min=0
    )
    purchase_decision = models.BooleanField(
        label="你是否购买这个商品?",
        choices=[
            [True, '是'],
            [False, '否']
        ],
        widget=widgets.RadioSelect
    )

    # 定义一个属性来获取玩家的配对
    @property
    def partner(self):
        if self.partner_id:
            return self.subsession.get_player_by_id(self.partner_id)
        return None

# 定义介绍页面
class Introduction(Page):
    def vars_for_template(self):
        player = self.player
        partner = player.partner
        if partner:
            print(
                f"Introduction Page - Player {player.id_in_group} role: {player.player_role}, partner: {partner.id_in_group}")
        else:
            print(f"Introduction Page - Player {player.id_in_group} role: {player.player_role}, no partner")
        return {
            'player_role': player.player_role,
            'partner_role': partner.player_role if partner else None,
        }

# 定义卖家决策页面
class SellerDecision(Page):
    form_model = 'player'
    form_fields = ['quality', 'price']

    def is_displayed(self):
        return 'F' in self.player.player_role

    def vars_for_template(self):
        player = self.player
        partner = player.partner
        if partner:
            print(
                f"SellerDecision Page - Player {player.id_in_group} role: {player.player_role}, partner: {partner.id_in_group}")
        else:
            print(f"SellerDecision Page - Player {player.id_in_group} role: {player.player_role}, no partner")
        return {
            'player_role': player.player_role,
            'partner_role': partner.player_role if partner else None,
        }

# 定义买家视图页面
class BuyerView(Page):
    def is_displayed(self):
        return 'C' in self.player.player_role

    def vars_for_template(self):
        player = self.player
        partner = player.partner
        if partner:
            print(
                f"BuyerView Page - Player {player.id_in_group} role: {player.player_role}, partner: {partner.id_in_group}")
        else:
            print(f"BuyerView Page - Player {player.id_in_group} role: {player.player_role}, no partner")
        return {
            'seller_quality': partner.quality if partner else None,
            'seller_price': partner.price if partner else None,
            'seller_role': partner.player_role if partner else None,
        }

# 定义买家决策页面
class BuyerDecision(Page):
    form_model = 'player'
    form_fields = ['purchase_decision']

    def is_displayed(self):
        return 'C' in self.player.player_role

    def vars_for_template(self):
        player = self.player
        partner = player.partner
        if partner:
            print(
                f"BuyerDecision Page - Player {player.id_in_group} role: {player.player_role}, partner: {partner.id_in_group}")
        else:
            print(f"BuyerDecision Page - Player {player.id_in_group} role: {player.player_role}, no partner")
        return {
            'seller_quality': partner.quality if partner else None,
            'seller_price': partner.price if partner else None,
            'seller_role': partner.player_role if partner else None,
        }

# 定义结果等待页面
class ResultsWaitPage(WaitPage):
    def after_all_players_arrive(self):
        pass

# 定义结果页面
class Results(Page):
    def vars_for_template(self):
        player = self.player
        partner = player.partner
        if partner:
            print(
                f"Results Page - Player {player.id_in_group} role: {player.player_role}, partner: {partner.id_in_group}")
        else:
            print(f"Results Page - Player {player.id_in_group} role: {player.player_role}, no partner")
        return {
            'role': player.player_role,
            'partner_role': partner.player_role if partner else None,
            'partner_purchase_decision': partner.purchase_decision if partner else None,
        }

# 定义页面顺序
page_sequence = [Introduction, SellerDecision, BuyerView, BuyerDecision, ResultsWaitPage, Results]

Write a reply

Set forum username