def calc_share_weird_states(data_individual_mixed, data_group_mixed):
    """ In some states the strategy of the algorithm does not
    perfectly align with the win-stay lose-shift strategy described
    in the paper. I calculate the share of those states here
    (there are very very few).

    Args:
        data_individual_mixed (DataFrame): Individual level data from the experiment
        data_group_mixed (DataFrame): Group level data from the experiments

    Returns:
        float: Share of weird states from all rounds in the experiments
    """
    
    # Round in which the algorithm did NOT play the price of 1 or 4
    # This happens rarely bcs the strategy in three-firm markets is not
    # perfect WSLS.
    data_algos_group = data_group_mixed.loc[~data_group_mixed['treatment'].isin(['2H0A', '3H0A'])].copy()
    n_price_not_1_or_4 = len(data_algos_group.loc[~data_algos_group['price_algorithm'].isin([1,4])]) 


    #  Similarly if the algo plays a price of 4 after an upwards deviation
    data_algos_individual = data_individual_mixed.loc[
                               ~data_individual_mixed['treatment'].isin(['2H0A', '3H0A'])
                            ].copy()

    # Note that those are in 1H1A and thus individual = Group from an otree-data perspective
    n_price_4_but_different_state = len(data_algos_individual.loc[
                                        (data_algos_individual['price_algorithm'] == 4) &
                                        (~data_algos_individual['price_lag_1'].isin([1,4])) & 
                                        (data_algos_individual['round']>1)
                                    ])
    share_weird_states = (n_price_not_1_or_4 + n_price_4_but_different_state) / len(data_algos_group)
    return share_weird_states