我如何仅对 Otree 中角色的玩家的属性值求和

How can i sum the values of an attribute only for the players of a role in Otree

我正在编写 public 商品游戏的一个版本,但使用的是角色。因此,我无法获得来自确定角色的玩家的总贡献总和。我尝试使用以下代码:

self.total_contribution1 = 总和( [p.contribution for p in self.get_players() if p.role== 'A'])

但是没有用,我只得到一个无效操作的错误

如果我不写那个代码的 "if part",它会运行,但是像那个那样的属性值变成 0

from otree.api import (
models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer,
Currency as c, currency_range
)
import random
import floppyforms as forms
import config_leex_1

author = 'Your name here'

doc = """
Simple public goods game
"""


class Constants(BaseConstants):
name_in_url = 'tiebout_incertidumbre'
players_per_group = 4
num_rounds = config_leex_1.PEMG_number_rounds #10
instructions_template = 'beec_mg/Instructions.html'
multiplier1 = 1
multiplier2 = 2
multiplier3 = 3
i = 1
j = 1
k = 1

class Subsession(BaseSubsession):
def creating_session(self):

    for p in self.get_players():
        p.endowment = random.randint(1, 100)
        p.prob = random.randint(0,100)
        # Random creation of endowments for every round

class Group(BaseGroup):

    total_contribution1 = models.CurrencyField(initial=0)
    total_contribution2 = models.CurrencyField(initial=0)
    total_contribution3 = models.CurrencyField(initial=0)
    mean_contribution1 = models.CurrencyField(initial=0)
    mean_contribution2 = models.CurrencyField(initial=0)
    mean_contribution3 = models.CurrencyField(initial=0)
    totalp1 = models.IntegerField(initial=0)
    totalp2 = models.IntegerField(initial=0)
    totalp3 = models.IntegerField(initial=0)
    individual_share1 = models.CurrencyField(initial=0)
    individual_share2 = models.CurrencyField(initial=0)
    individual_share3 = models.CurrencyField(initial=0)

    def set_payoffs(self):
        # NOTA 1: LAS SUMAS CON FOR NO ESTÁN FUNCIONANDO, YA QUE DAN DE         
        VALOR 0
        # NOTA 2: Los sums con if botan un error de invalid operation
        # NOTA 3: Segun SO, se deberia incluir parentesis después de p.role
    # if p.role== 'A':
    # self.total_contribution1 = sum(
        # [p.contribution for p in self.get_players() if p.role() == 'A'])
        for p in self.get_players():
            if p.role() == 'A':
                self.total_contribution1=+ p.contribution

        for p in self.get_players():
            if p.role() == 'B':
                self.total_contribution2=+ p.contribution

        for p in self.get_players():
            if p.role() == 'C':
                self.total_contribution3=+ p.contribution

        # if p.role== 'B'
        # self.total_contribution2 = sum(
        # [p.contribution for p in self.get_players()])
        # if p.role== 'C'
        # self.total_contribution3 = sum(
        # [p.contribution for p in self.get_players()])

        # if p.role== 'A'
        # self.totalp1 = sum(
        # [p.counter for p in self.get_players() if p.role() == 'A'])
        for p in self.get_players():
            if p.role() == 'A':
                self.totalp1=+1

        for p in self.get_players():
            if p.role() == 'B':
                self.totalp2=+1

        for p in self.get_players():
            if p.role() == 'C':
                self.totalp3=+1

        # if p.role == 'B'
    # self.totalp2 = sum(
        # [p.counter for p in self.get_players() if p.role() == 'B'])
    # if p.role == 'C'
    # self.totalp3 = sum(
        # [p.counter for p in self.get_players() if p.role() == 'C'])

    self.individual_share1 = self.total_contribution1 *         
    Constants.multiplier1 / self.totalp1
    self.individual_share2 = self.total_contribution2 *                 
    Constants.multiplier2 / self.totalp2
    self.individual_share3 = self.total_contribution3 * 
    Constants.multiplier3 / self.totalp3

    self.mean_contribution1 = self.total_contribution1/self.totalp1
    self.mean_contribution2 = self.total_contribution2 /self.totalp2
    self.mean_contribution3 = self.total_contribution3 /self.totalp3


    for p in self.get_players():
        if p.role == "A":
            p.payoff = p.endowment - p.contribution + self.individual_share1
        elif p.role == "B":
            if p.prob <= 75:
                p.payoff = p.endowment - p.contribution + 
    self.individual_share2
            else:
                p.payoff = p.endowment - p.contribution
        else:
            if p.prob <= 50:
                p.payoff = p.endowment - p.contribution + 
    self.individual_share3
            else:
                p.payoff = p.endowment - p.contribution

class Player(BasePlayer):
    prob =models.IntegerField(min=0, max=100)
    endowment = models.CurrencyField(min=0, max=100, initial=0)
    contribution = models.CurrencyField(verbose_name='Deslice hasta 
    seleccionar la cantidad a enviar deseada',
                                    min=0,max=100,
                                    initial=0,widget=widgets.SliderInput())
    counter = models.IntegerField(initial=1)
    roller = models.IntegerField(verbose_name='Deslice hasta seleccionar el 
    número de la opción deseada',
                             min=1, max=3,
                             widget=widgets.SliderInput())
   # Se está usando un slider para esta opción pues permite evitar 
   confusiones en caso se use un grupo de botones
   # los cuales se podrían clickear en cualquier momento sin que el jugador 
   entienda si ya se registró o no su decisión

   def role(self):
      if self.roller == 1:
          return 'A'
      elif self.roller == 2:
          return 'B'
      else:
          return 'C'from otree.api import (

role 是方法而不是字段。 所以要让它工作,你需要使用这个:

self.total_contribution1 = sum( [p.contribution for p in self.get_players() if p.role() == 'A'])

注意我在role

后面加的括号