<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def map_statistic(self, plot):
 """ Mapping aesthetics to computed statistics """

        data = self.data
        if not len(data):
            return type(data)()

        # Assemble aesthetics from layer, plot and stat mappings
        aesthetics = deepcopy(self.mapping)
        if self.inherit_aes:
            aesthetics = defaults(aesthetics, plot.mapping)

        aesthetics = defaults(aesthetics, self.stat.DEFAULT_AES)

        # The new aesthetics are those that the stat calculates
        # and have been mapped to with dot dot notation
        # e.g aes(y='..count..'), y is the new aesthetic and
        # 'count' is the computed column in data
        new = {}  # {'aesthetic_name': 'calculated_stat'}
        stat_data = type(data)()
        stat_namespace = dict(stat=stat)
        env = plot.environment.with_outer_namespace(stat_namespace)
        for ae in get_calculated_aes(aesthetics):
            new[ae] = strip_calculated_markers(aesthetics[ae])
            # In conjuction with the pd.concat at the end,
            # be careful not to create duplicate columns
            # for cases like y='..y..'
            if new[ae] != ae:
                stat_data[ae] = env.eval(
                    new[ae], inner_namespace=data)

        if not new:
            return

        # (see stat_spoke for one exception)
        if self.stat.retransform:
            stat_data = plot.scales.transform_df(stat_data)

        # When there are duplicate columns, we use the computed
        # ones in stat_data
        columns = data.columns.difference(stat_data.columns)
        self.data = pd.concat([data[columns], stat_data], axis=1)

        # Add any new scales, if needed
        plot.scales.add_defaults(self.data, new)