o
    [hA#                     @   s   d dl mZ d dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZ d dlmZ d dlmZ d dlZd dlZd dlmZ d d	lmZmZmZmZmZ d d
lmZ d dlmZmZmZmZm Z  G dd de!Z"G dd de"Z#G dd dee Z$dS )    )declared_attrN)defaultdict)Column
ForeignKey)relationship)sqltypes)func)BaseConstants)get_models_modulein_round	in_roundsget_constantsget_builtin_constant)has_group_by_arrival_time)dbdbqvalues_flatSPGModelMixinSessionFKc                   @      e Zd ZdS )GroupMatrixErrorN__name__
__module____qualname__ r   r   ~/home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/otree/models/subsession.pyr          r   c                   @   r   )RoundMismatchErrorNr   r   r   r   r   r      r   r   c                   @   s   e Zd ZdZeejddZdd Zdd Z	dd Z
d	d
 Zdd Zdd Zdd Zd3ddZdd Zdd ZedefddZdd Zdd Zedd  Zdd!d"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zed.d/ Z ed0d1 Z!d2S )4BaseSubsessionT)indexc                 C   s   t t| || jdS Nsession)r   typer#   )selfround_numberr   r   r   r   *   s   zBaseSubsession.in_roundc                 C   s   t t| ||| jdS r!   )r   r$   r#   )r%   firstlastr   r   r   r   -   s   zBaseSubsession.in_roundsc                 C   s   |  d| jd S )N   )r   r&   r%   r   r   r   in_previous_rounds0   s   z!BaseSubsession.in_previous_roundsc                 C   s   |   | g S N)r+   r*   r   r   r   in_all_rounds3      zBaseSubsession.in_all_roundsc                 C      t | jdS )Nid_in_subsession)list	group_setorder_byr*   r   r   r   
get_groups6      zBaseSubsession.get_groupsc                 C   r/   )Nid)r1   
player_setr3   r*   r   r   r   get_players9   r5   zBaseSubsession.get_playersc                 C   sn   |   }|  }t|||j| k|jd}tt	}|D ]}||j
j |r,|n|j q t	| S )NZid_in_group)_PlayerClass_GroupClassr   joinfilter
subsessionr3   r0   r   r1   groupappendvalues)r%   objectsPlayerGroupZplayersdpr   r   r   _get_group_matrix<   s   
z BaseSubsession._get_group_matrixFc                 C   s   | j |dS )N)rA   )rF   )r%   rA   r   r   r   get_group_matrixJ   s   zBaseSubsession.get_group_matrixc           	         s   z|d d }W n t y   tddw t|tr!dd |D }dd |D }t|}|   |ttdt d ksDd}t|d fd	d|D }| j	
|  jdi | j  |  }t|dd
D ]\}}|j| || j| jd}|| qgdS )zN
        warning: this deletes the groups and any data stored on them
        r   z%Group matrix must be a list of lists.Nc                 S   s   g | ]	}d d |D qS )c                 S      g | ]}|j qS r   )r0   .0rE   r   r   r   
<listcomp>X       >BaseSubsession.set_group_matrix.<locals>.<listcomp>.<listcomp>r   rJ   rowr   r   r   rK   X       z3BaseSubsession.set_group_matrix.<locals>.<listcomp>c                 S   s   g | ]	}|D ]}|qqS r   r   )rJ   rO   iisr   r   r   rK   Z   rP   r)   z@The matrix of integers either has duplicate or missing elements.c                    s   g | ]} fd d|D qS )c                    s   g | ]} |d   qS )r)   r   )rJ   rQ   Zplayers_from_dbr   r   rK   c   s    rM   r   rN   rR   r   r   rK   c   s    )startr=   r0   r#   r&   )	TypeErrorr   
isinstancer   sortedr8   r1   rangelenr7   updater9   Zgroup_idr2   deleter:   	enumerateZobjects_creater#   r&   set_players)	r%   matrixZsample_itemZids_flatmsgZ
GroupClassirO   r>   r   rR   r   set_group_matrixM   s4   



	zBaseSubsession.set_group_matrixc                 C   s    |  |}| }| | d S r,   )r   rG   ra   )r%   r&   Zprevious_roundgroup_matrixr   r   r   group_like_roundu   s   
zBaseSubsession.group_like_roundreturnc                 C   s   t |  S r,   )r   get_folder_namer*   r   r   r   
_Constantsz   s   zBaseSubsession._Constantsc                 C      t |  jS r,   )r
   re   rC   r*   r   r   r   r:   ~   r.   zBaseSubsession._GroupClassc                 C   rg   r,   )r
   re   rB   r*   r   r   r   r9      r.   zBaseSubsession._PlayerClassc                 C   s   |   }t|S r,   )re   r   )clsZapp_namer   r   r   _has_group_by_arrival_time   s   z)BaseSubsession._has_group_by_arrival_time)fixed_id_in_groupc                C   s$   |   }tj||}| | d S r,   )rG   otreecommonZ_group_randomlyra   )r%   rj   rb   r   r   r   group_randomly   s   zBaseSubsession.group_randomlyc                 C   s   d S r,   r   r*   r   r   r   creating_session      zBaseSubsession.creating_sessionc                 C   s   i S r,   r   r*   r   r   r   vars_for_admin_report   ro   z$BaseSubsession.vars_for_admin_reportc              
      s  ddl m} |  }d}t| j||jdk|jdk|j	|k|j
dk|jt | k}|  }t|dt| j}|| |}|sDdS dd	 |D }	|  }
| j}|d
}d}t| j|d D ]V}| |}|j|jdd	 |	D }dd |D   fdd	|	D }|  ||
| j|d}t| || || jkr|}|j||j dkD ]}t!| qqa|	D ]}d|_
d|_q|S )z;Returns the group ID of the participants who were regroupedr   )ParticipantF   TFgroup_by_arrival_time_methodNc                 S   rH   r   participantrI   r   r   r   rK      rL   z>BaseSubsession._gbat_try_to_make_new_group.<locals>.<listcomp>
num_roundsr)   c                 S   rH   r   )r6   )rJ   ppr   r   r   rK      rL   c                 S   s   i | ]}|j |qS r   rt   )rJ   Zplayerr   r   r   
<dictcomp>       z>BaseSubsession._gbat_try_to_make_new_group.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   )rJ   ru   Zparticipant_ids_to_playersr   r   rK      ry   rT   )"Zotree.modelsrq   r9   r1   r7   r;   r<   Z_gbat_is_connectedZ_gbat_tab_hiddenZ_index_in_pagesZ_gbat_groupedZ_last_request_timestamptimeZget_user_defined_targetgetattrr$   rs   !_gbat_next_group_id_in_subsessionrf   get_normalizedrX   r&   r   Zparticipant_idin_r:   r#   r   addr]   r2   Z	outerjoinr6   r[   )r%   Z
page_indexrq   rB   ZSTALE_THRESHOLD_SECONDSwaiting_playerstargetr   Zplayers_for_groupZparticipantsZgroup_id_in_subsession	Constantsrv   Zthis_round_new_groupr&   r=   Zunordered_playersZordered_players_for_groupr>   Zgroup_to_deleteru   r   rz   r   _gbat_try_to_make_new_group   st   







z*BaseSubsession._gbat_try_to_make_new_groupc                 C   s*   |   }tt|jj| jd d S )Nr"   r)   )r:   r   r   maxr0   Z	filter_byr#   Zscalar)r%   rC   r   r   r   r}      s   z0BaseSubsession._gbat_next_group_id_in_subsessionc                 C   s@   | j }|d}|d u rd}t|t||kr|d | S d S )NZplayers_per_groupzIf using group_by_arrival_time, you must either set Constants.players_per_group to a value other than None, or define group_by_arrival_time_method.)rf   r~   AssertionErrorrY   )r%   r   r   Zppgr_   r   r   r   rs      s   
z+BaseSubsession.group_by_arrival_time_methodc                 C      t | j ddddS )Nz.Groupr=   dynamicZback_populatesZlazyr   r   rh   r   r   r   r2         zBaseSubsession.group_setc                 C   r   )Nz.Playerr=   r   r   r   r   r   r   r   r7     r   zBaseSubsession.player_setN)F)"r   r   r   Z__abstract__CstIntegerr&   r   r   r+   r-   r4   r8   rF   rG   ra   rc   propertyr	   rf   r:   r9   classmethodri   rm   rn   rp   r   r}   rs   r   r2   r7   r   r   r   r   r   "   s@    
(
O
r   )%Zsqlalchemy.ext.declarativer   copyr{   collectionsr   Z
sqlalchemyr   r   r   Zsqlalchemy.ormr   Zsqlalchemy.sqlr   r   Zsqlalchemy.sql.functionsr   Zotree.commonrk   Zotree.databaseZotree.constantsr	   r
   r   r   r   r   r   r   r   r   r   r   
ValueErrorr   r   r   r   r   r   r   <module>   s"    