예제 #1
0
def strategy_statuses(creative_statuses):
    '''Fixture with one strategy with all available statuses and another clean'''
    strategy_problematic = {'name': 'Strategy problematic', 'campaign': 'I\'m a fruit',
                  'budget_total': 0, 'budget_bid_CPM': Decimal('0.1')}
    strategy_clean = {'name': 'Strategy clean', 'campaign': 'I\'m a fruit',
                  'budget_total': 1000, 'budget_bid_CPM': Decimal('0.1')}

    setup = creative_statuses
    setup.setup_landing_pages()
    setup.setup_campaigns()

    setup.setup_strategies([strategy_problematic, strategy_clean])

    ADVERTS = [
        {'name': 'Ad audited', 'strategy': 'Strategy clean',
         'creative': 'Image audited'},
        {'name': 'Ad audited', 'strategy': 'Strategy problematic',
         'creative': 'Image audited'},
        {'name': 'Ad audit pending', 'strategy': 'Strategy problematic',
         'creative': 'Image audit pending'},
        {'name': 'Ad audit rejected', 'strategy': 'Strategy problematic',
         'creative': 'Image audit rejected'},
        {'name': 'Ad audit blocked', 'strategy': 'Strategy problematic',
         'creative': 'Image audit blocked'},
        {'name': 'Ad audit expired', 'strategy': 'Strategy problematic',
         'creative': 'Image audit expired'}
    ]

    for advert in ADVERTS:
        advert.update({'url': 'http://www.google.com/'})
        setup.setup_adverts([advert])

    call_command('rebuild_index', interactive=False)

    return setup
예제 #2
0
def distribute_sum_randomly(n, total):
    """
    Return a randomly chosen list of n numbers summing to total.
    Depends on total type values will be integers or Decimals.

    Examples:
    >>> distribute_sum_randomly(5, 100)
    >>> [5, 21, 57, 13, 4]

    >>> distribute_sum_randomly(3, Decimal('84.65'))
    >>> [Decimal('41.94'), Decimal('27.15'), Decimal('15.56')]
    """
    if total == 0 or total == Decimal('0'):
        return [total for i in xrange(0, n)]

    dividers = []
    for i in xrange(1, n):
        if isinstance(total, int):
            divider = random.randint(1, total)
        else:
            divider_decimal = random.random() * float(total)
            divider = Decimal('%f' % divider_decimal)
        dividers.append(divider)

    dividers.sort()

    return [a - b for a, b in zip(dividers + [total], [0] + dividers)]
예제 #3
0
def db_factory_four_strategies(bidding_app):
    strategies = [
        {'name': 'Strategy 3', 'campaign': 'I\'m a fruit',
         'budget_total': 8000, 'budget_bid_CPM': Decimal('0.1')},
        {'name': 'Strategy 4', 'campaign': 'I\'m a fruit',
         'budget_total': 4321, 'budget_bid_CPM': Decimal('0.1')}
    ]
    bidding_app.setup_strategies(strategies)
    return bidding_app
예제 #4
0
    def total_spent(self):
        """
        Sum of all account spendings (commission included).
        """
        aggregation = self.campaign_set.aggregate(
            sum=Sum('budget_spent'), commission=Sum('budget_spent_commission'))

        return (aggregation['sum'] or Decimal(0)) + \
               (aggregation['commission'] or Decimal(0)) + \
            self.audit_fees
예제 #5
0
    def get_randomized_metrics(self, budget, base_cpm):
        """
        Generate basic metrics values within ranges provided in configuration

        :return: values for BASE_METRICS
        :rtype: dict
        """

        conf = self.options
        commission_value = budget / (Decimal(1) + COMMISSION)
        inventory_cost = budget - commission_value
        data_cost_value = randint(
            *conf['DATA_COST_RANGE']) / Decimal(100) * inventory_cost
        imp_value = inventory_cost - data_cost_value
        cpm = randint(*conf['BID_CPM_RANGE']) / Decimal(100) * base_cpm
        imp = imp_value * 1000 / cpm
        ctr = randint(*conf['CTR_RANGE']) / Decimal(100)
        clk = imp * ctr
        conv_rate = randint(*conf['CONV_RATE_RANGE']) / Decimal(100)
        conv = clk * conv_rate
        conv_value = conv * randint(*conf['CONV_VALUE_RANGE']) / Decimal(100)

        return {
            'imp': imp.quantize(Decimal('1')),
            'imp_value': imp_value,
            'clk': clk.quantize(Decimal('1')),
            'conv': conv.quantize(Decimal('1')),
            'conv_value': conv_value,
            'data_cost_value': data_cost_value,
            'commission_value': commission_value,
        }
예제 #6
0
def campaign_time_spent_ratio(campaign):
    """
    Calculate part of campaign that has elapsed

    :return: Ratio between 0.0 and 1.0
    :rtype: Decimal
    """
    campaign_duration = int((campaign.end_UTC - campaign.start_UTC).total_seconds())
    campaign_elapsed = int((datetime.utcnow() - campaign.start_UTC).total_seconds())
    if campaign_elapsed < 0:
        return Decimal(0)
    return Decimal(campaign_elapsed) / campaign_duration
예제 #7
0
def test_strategy_overall(client, fill_db):
    '''
    Tries to save strategy without required fields,
    Check errors and fill inputs with proper data.
    Saves strategy and checks UI and DB.
    '''
    EDITED_STRATEGY = {
        'name': 'Strategy Edited',
        'budget': '50',
        'budget-daily': '20',
    }

    ERRORS = {
        'name_required': 'Strategy name: This field is required.',
        'budget_required': 'Total strategy budget: This field is required.',
    }

    INPUTS = ['name', 'budget', 'budget-daily']

    utils.go_to_step(client, 'overall', existing=True)

    # Clear all inputs
    for input_name in INPUTS:
        client.get_input(input_name).clear()

    # Try to save and check if correct errors are displayed
    client.click_on_class('button-save-changes')
    client.wait_for_modal()
    modal_errors = client.get_modal_errors()

    assert len(modal_errors) == len(ERRORS)
    for key in ERRORS.keys():
        assert ERRORS[key] in modal_errors

    client.close_modal()

    # Fill inputs with proper data
    for input_name in INPUTS:
        client.send_keys(input_name, EDITED_STRATEGY[input_name])

    # Save again and check UI and DB
    utils.save_and_return_to_step(client)

    for input_name in INPUTS:
        assert client.get_input_val(input_name) == EDITED_STRATEGY[input_name]

    strategy = Strategy.objects.all()[0]

    assert strategy.name == EDITED_STRATEGY['name']
    assert strategy.budget_total == Decimal(EDITED_STRATEGY['budget'])
    assert strategy.budget_daily == Decimal(EDITED_STRATEGY['budget-daily'])
예제 #8
0
def test_derivative_metrics(state_app, report_class, related_class,
                            related_object_attr, imp_value, imp, clk, conv,
                            conv_value, commission_value, data_cost_value):
    imp_value_total = imp_value + commission_value + data_cost_value
    net_earned = conv_value - imp_value_total

    report = report_class(time=datetime.utcnow(),
                          imp=imp,
                          imp_value=imp_value,
                          clk=clk,
                          conv=conv,
                          conv_value=conv_value,
                          commission_value=commission_value,
                          data_cost_value=data_cost_value)
    report.related = related_class.objects.first()
    report.save()

    aggregation = report_class.objects.report_table(related_obj=getattr(
        report.related, related_object_attr),
                                                    sort_by='imp')

    assert len(aggregation) == 1

    report_data = aggregation[0]

    ecpm = ctr = ecpc = ecpa = conv_rate = roi = Decimal(0)

    if imp_value:
        roi = (conv_value - imp_value_total) / imp_value_total * 100

    if clk:
        ecpc = imp_value_total / clk
        conv_rate = conv / clk * 100

    if imp:
        ecpm = imp_value_total / imp * 1000
        ctr = clk / imp * 100

    if conv:
        ecpa = imp_value_total / conv

    prec = Decimal('1.0000000')

    for metric in [
            'ecpc', 'ecpa', 'ecpm', 'ctr', 'conv_rate', 'roi', 'net_earned'
    ]:
        a = report_data[metric].quantize(prec)
        b = locals().get(metric).quantize(prec)
        assert a == b
예제 #9
0
def campaign_statuses(creative_statuses):
    '''Campaigns with all possible statuses'''
    campaign_finished = {'name': 'Campaign finished', 'account': 'acc',
                         'start_UTC': utcnow_with_timedelta(days=-7),
                         'end_UTC': utcnow_with_timedelta(days=-3),
                         'budget_total': 2000, 'budget_spent': 2000,
                         'landing_site': 'http://www.google.com/'}

    campaign_running = {'name': 'Campaign running', 'account': 'acc',
                         'start_UTC': utcnow_with_timedelta(days=-4),
                         'end_UTC': utcnow_with_timedelta(days=3),
                         'budget_total': 8000, 'landing_site': 'http://www.google.com/'}

    campaign_scheduled = {'name': 'Campaign scheduled', 'account': 'acc',
                         'start_UTC': utcnow_with_timedelta(days=10),
                         'end_UTC': utcnow_with_timedelta(days=13),
                         'budget_total': 1000, 'landing_site': 'http://www.google.com/'}

    strategy_a = {'name': 'Strategy A', 'campaign': 'Campaign finished',
                  'budget_total': 1000, 'budget_bid_CPM': Decimal('0.1')}
    strategy_b = {'name': 'Strategy B', 'campaign': 'Campaign running',
                  'budget_total': 0, 'budget_bid_CPM': Decimal('0.1')}
    strategy_c = {'name': 'Strategy C', 'campaign': 'Campaign scheduled',
                  'budget_total': 100, 'budget_bid_CPM': Decimal('0.1')}

    setup = creative_statuses
    setup.setup_landing_pages()
    setup.setup_campaigns([campaign_finished, campaign_running, campaign_scheduled])
    setup.setup_strategies([strategy_a, strategy_b, strategy_c])
    ADVERTS = [
        {'name': 'Ad audited', 'strategy': 'Strategy A',
         'creative': 'Image audited'},
        {'name': 'Ad audit pending', 'strategy': 'Strategy B',
         'creative': 'Image audit pending'},
        {'name': 'Ad audit rejected', 'strategy': 'Strategy B',
         'creative': 'Image audit rejected'},
        {'name': 'Ad audit blocked', 'strategy': 'Strategy C',
         'creative': 'Image audit blocked'},
        {'name': 'Ad audit expired', 'strategy': 'Strategy C',
         'creative': 'Image audit expired'}
    ]
    for advert in ADVERTS:
        advert.update({'url': 'http://www.google.com/'})
        setup.setup_adverts([advert])

    call_command('rebuild_index', interactive=False)

    return setup
예제 #10
0
def test_aggregate_dateranges(state_app, report_class, related_class,
                              related_obj_attr):
    related = related_class.objects.first()

    for (dt, data_cost_value, imp, imp_value, clk, conv,
         conv_value) in REPORT_DATA:
        report = report_class(
            time=dt,
            imp=imp,
            imp_value=imp_value,
            clk=clk,
            conv=conv,
            conv_value=conv_value,
            data_cost_value=data_cost_value,
        )
        report.related = related
        report.save()

    def check_aggregation(start_date, end_date, imp, imp_vt):
        '''
        asserts imp and imp_value_total
        '''

        [aggregation] = report_class.objects.report_table(
            related_obj=getattr(related, related_obj_attr),
            sort_by='imp',
            start_date=start_date,
            end_date=end_date,
        )

        assert aggregation['imp'] == imp
        assert aggregation['imp_value_total'] == imp_vt

    # DATERANGE: 2014-04-01 - 2014-04-01
    check_aggregation(
        start_date=DT0.date(),
        end_date=DT0.date(),
        imp=Decimal('77'),
        imp_vt=Decimal('325'),
    )

    # DATERANGE: 2014-04-01 - 2014-04-02
    check_aggregation(
        start_date=DT0.date(),
        end_date=DT2.date(),
        imp=Decimal('106'),
        imp_vt=Decimal('412'),
    )
예제 #11
0
    def test_strategy_set_period_budgets(self, rc, period_budgets_app):
        '''
        Test setting strategy budgets in Redis
        '''

        strategy = Strategy.objects.first()
        strategy.is_distributed_evenly = True
        strategy.save()

        assert strategy.state.is_running is True

        # Save period budgets
        saved_budgets = Strategy.reset_period_budgets(rc)

        # Check if they were saved
        retrieved_budgets = rc.hgetall(Strategy.period_budgets_key)

        assert len(retrieved_budgets) == len(saved_budgets)
        assert strategy.public_id in retrieved_budgets
        assert Decimal(retrieved_budgets[strategy.public_id]) == \
               saved_budgets[strategy.public_id]

        # this should take strategy off distribute evenly loop
        strategy.is_distributed_evenly = False
        strategy.save()

        # Try to remove them and check if they were removed
        saved_budgets = Strategy.reset_period_budgets(rc)

        assert rc.hgetall(Strategy.period_budgets_key) == {}, "Period budgets should be cleared!"
예제 #12
0
def test_edit_campain_conversion(client, fill_db):
    conv_data = {
        'name': 'Here comes the conversion',
        'value': '5',
    }

    go_to_campaign_step(client, 'conversion')

    for item in ('name', 'value'):
        # Clear input
        input = client.get_input('conversion-%s' % item)
        input.clear()

        modal_errors = save_with_errors(client)

        assert ERRORS['conversion_%s_required' % item] in modal_errors
        assert client.has_class(input, 'input-error') is True

        client.close_modal()

        # Write proper value
        client.send_keys(input, conv_data['%s' % item])

    save_and_return(client, 'conversion')

    # Check UI and DB
    assert client.get_input('conversion-name').get_attribute('value') == conv_data['name']
    assert client.get_input('conversion-value').get_attribute('value') == conv_data['value']

    campaign = Campaign.objects.get(name='I\'m a fruit')

    assert campaign.conversion_def.name == conv_data['name']
    assert campaign.conversion_def.value == Decimal(conv_data['value'])
예제 #13
0
def audit_app(basic_fixture):
    setup = DatabaseDataFactory()
    setup.setup_accounts()
    setup.setup_users()

    landing_pages = default_landing_page + \
                    [{'owner': 'acc', 'url': 'http://www.onet.com/'}]
    setup.setup_landing_pages(landing_pages)

    campaigns = default_campaign + [{
        'name': 'Meat',
        'account': 'acc',
        'budget_total': 8000,
        'start_UTC': '2013-01-01T00:00',
        'end_UTC': '2013-01-31T00:00',
        'landing_site': 'http://www.onet.com/'
    }]
    setup.setup_campaigns(campaigns)
    strategies = default_strategies + [{
        'name': 'Roast beef',
        'campaign': 'Meat',
        'budget_total': 67676,
        'budget_bid_CPM': Decimal('0.1')
    }]
    setup.setup_strategies(strategies)
    setup.setup_creative_images()
    return setup
예제 #14
0
def db_round(dec):
    '''
    Return decimal rounded to the precision that tolerates cummulative
    differences of precision in Python and Postgres.
    '''
    prec = Decimal('1e-14')  # Use precision that is 'good enough'.
    return dec.quantize(prec)
예제 #15
0
def test_period_budget(bidding_periods_app, budget_daily, budget_daily_spent,
                       budget_total, budget_total_spent, ratio, now,
                       period_budget):
    """ Check value of budget with different values of daily and total budget and daily and total spend. """
    class MyStrategy(TestStrategy):

        def bidding_periods_ratio(self):
            return self.__bidding_periods_ratio

        def set_bidding_periods_ratio(self, ratio):
            self.__bidding_periods_ratio = ratio

    campaign = Campaign.objects.all().first()
    campaign.end_UTC = datetime(2014, 10, 21, 01, 00, 00)
    campaign.save()

    strategy = MyStrategy(
        name='Strategy Cool',
        campaign=campaign,
        budget_total=budget_total,
        budget_daily=budget_daily,
        budget_bid_CPM=0.2
    )

    strategy.set_bidding_periods_ratio(ratio)
    strategy.budget_spent = budget_total_spent
    strategy.budget_daily_spent = budget_daily_spent

    assert strategy.period_budget(now) == Decimal(period_budget)
예제 #16
0
def test_aggregate_correctnes(state_app, report_class, related_class,
                              related_object_attr, imp_value, imp, clk, conv,
                              conv_value, imp_value_total, data_cost_value):
    now = datetime.utcnow()
    later = now + timedelta(hours=1, minutes=13)
    related = related_class.objects.first()
    report1 = report_class(time=now,
                           imp_value=imp_value[0],
                           imp=imp[0],
                           clk=clk[0],
                           conv=conv[0],
                           conv_value=conv_value[0],
                           data_cost_value=data_cost_value[0])
    report1.related = related
    report1.save()

    report2 = report_class(time=later,
                           imp_value=imp_value[1],
                           imp=imp[1],
                           clk=clk[1],
                           conv=conv[1],
                           conv_value=conv_value[1],
                           data_cost_value=data_cost_value[1])
    report2.related = related
    report2.save()

    aggregation = report_class.objects.report_table(
        related_obj=getattr(related, related_object_attr),
        start_date=date.today(),
        end_date=date.today() + timedelta(days=1),
        sort_by='imp',
    )
    assert len(aggregation) == 1
    report_data = aggregation[0]

    # All values needs to be cast to string, due to different precision
    # available, and the fact, that sometimes, I got a little more digits
    # when casting Decimal to float, than from operations on floats alone

    ecpm = ctr = ecpc = conv_rate = roi = Decimal(0)

    if sum(imp_value_total):
        numerator = sum(conv_value) - sum(imp_value_total)
        denominator = sum(imp_value_total)
        roi = (numerator / denominator) * 100

    if sum(clk):
        ecpc = sum(imp_value_total) / sum(clk)
        conv_rate = (sum(conv) / sum(clk)) * 100

    if sum(imp):
        ecpm = (sum(imp_value_total) / sum(imp)) * 1000
        ctr = (sum(clk) / sum(imp)) * 100

    assert db_round(report_data['ecpm']) == db_round(ecpm)
    assert db_round(report_data['ctr']) == db_round(ctr)
    assert db_round(report_data['ecpc']) == db_round(ecpc)
    assert db_round(report_data['conv_rate']) == db_round(conv_rate)
    assert db_round(report_data['roi']) == db_round(roi)
예제 #17
0
파일: fields.py 프로젝트: sorlandet/code
 def to_precision(cls, dec):
     '''
     Return rounded decimal for easy comparisions.
     :param Decimal dec: decimal to quantize
     :return Decimal: copy of dec, quantized to class precision
     '''
     precision = Decimal('0.1')**cls.decimal_places
     return dec.quantize(precision)
예제 #18
0
    def total_paid(self):
        """
        Sum of payments account made.

        :returns: money balance for a given account
        :rtype: Decimal

        """
        return self.payment_set.aggregate(
            sum=Sum('amount'))['sum'] or Decimal(0)
예제 #19
0
def period_validation_app(app):
    strategies = [
        {'name': 'Hello this is Citrus', 'campaign': 'I\'m a fruit',
         'budget_total': 12345, 'budget_daily': 12345,
         'budget_bid_CPM': Decimal('0.2')}
    ]
    app.setup.setup_landing_pages()
    app.setup.setup_campaigns_running()
    app.setup.setup_strategies(strategies)
    return app
예제 #20
0
    def fake_campaign_report(self, campaign):
        """Fake all reports related to Campaign and Strategy model for a single campaign"""

        def total_spent(metrics_dict):
            return (metrics_dict['imp_value']
                    + metrics_dict['data_cost_value']
                    + metrics_dict['commission_value'])

        campaign_time_spent = Decimal(campaign_time_spent_ratio(campaign))
        campaign_budget_left = campaign.budget_total * campaign_time_spent

        campaign_metrics = {
            'imp': 0,
            'imp_value': Decimal('0'),
            'clk': 0,
            'conv': 0,
            'conv_value': Decimal('0'),
            'data_cost_value': Decimal('0'),
            'commission_value': Decimal('0'),
        }

        for strategy in campaign.strategy_set.all():
            strategy_spent = strategy.budget_total * campaign_time_spent
            effective_spent = min(campaign_budget_left, strategy_spent)

            strategy_metrics = self.fake_strategy_report(strategy, effective_spent)

            if strategy_metrics:
                reported_spent = total_spent(strategy_metrics)
                campaign_budget_left -= reported_spent
                strategy.budget_spent = reported_spent
                strategy.save()

                for metric, value in strategy_metrics.iteritems():
                    campaign_metrics[metric] += value

        campaign_spent = total_spent(campaign_metrics)

        campaign.budget_spent = campaign_spent
        campaign.save()

        self.create_campaign_reports(campaign, campaign_metrics)
예제 #21
0
    def test_save_model_spending(self, bidding_app):
        '''
        save_object_spending gets django model object and saves given
        spending value and spending time
        '''
        saved_strat = bidding_app.models['strategy']['Hello this is Citrus']
        saved_strat.save_spending(5, 1)
        saved_strat.save_daily_spending(1)

        strategy = Strategy.objects.get(pk=saved_strat.pk)
        assert strategy.budget_spent == Decimal('5') / offset
        assert strategy.budget_daily_spent == Decimal('1') / offset
        assert strategy.budget_spent_commission == Decimal('1') / offset

        saved_camp = bidding_app.models['campaign']['I\'m a fruit']
        saved_camp.save_spending(5, 1)

        campaign = Campaign.objects.get(pk=saved_camp.pk)
        assert campaign.budget_spent == Decimal('5') / offset
        assert campaign.budget_spent_commission == Decimal('1') / offset
예제 #22
0
    def test_save_spendings(self, db_factory_four_strategies):
        '''
        save spendings takes spendings generated by get_spendings function
        and stores them in database via django active record.
        '''
        strategies = db_factory_four_strategies.models['strategy']

        strat_obj_spends = {
            strategies['Hello this is Citrus'].public_id: (30, 3, 123),
            strategies['han i has a pumpkin?'].public_id: (40, 4, 321),
            strategies['Strategy 3'].public_id: (1, 1, 31),
        }

        saved_models = Strategy.save_spendings(strat_obj_spends)

        assert len(saved_models) == 3
        strat1 = Strategy.objects.get(pk=strategies['Hello this is Citrus'].pk)
        strat2 = Strategy.objects.get(pk=strategies['han i has a pumpkin?'].pk)
        strat3 = Strategy.objects.get(pk=strategies['Strategy 3'].pk)

        assert strat1.budget_spent == Decimal('30') / offset
        assert strat1.budget_spent_commission == Decimal('3') / offset

        assert strat2.budget_spent == Decimal('40') / offset
        assert strat2.budget_spent_commission == Decimal('4') / offset

        assert strat3.budget_spent == Decimal('1') / offset
        assert strat3.budget_spent_commission == Decimal('1') / offset
예제 #23
0
def test_bidding_periods_nonzero(bidding_periods_app, strategy_bid, periods,
                                 ads, nonzero_periods):

    strategy = Strategy.objects.get(name='Hello this is Citrus')
    strategy.is_day_parted = True
    strategy.budget_bid_CPM = Decimal(strategy_bid)
    strategy.save()
    setup_bidding_periods(strategy, periods)
    setup_bidding_ads(strategy, ads)

    calculated_period_ids = [p.pk for p in strategy._bidding_periods_nonzero()]
    expected_period_ids = [p.pk for p in get_expected_periods(nonzero_periods)]

    assert sorted(calculated_period_ids) == sorted(expected_period_ids)
예제 #24
0
def test_update_bidder_spendings(redisdb_spendings, bidding_app):
    """
    Create a redis spending entries for campaign.
    Check redis pubsub channel for correct message.
    """
    # no point in this test if we don't have any campaign here
    assert Campaign.objects.count() > 0

    # let's patch publish method to intercept published message
    with patch.object(update_bidder_spendings.rd, 'publish'):
        for campaign in Campaign.objects.all():
            redisdb_spendings.hset(
                adserving.bidder.spendings.spend_camp_key,
                campaign.public_id,
                Decimal('0.8')
            )
            redisdb_spendings.hset(
                adserving.bidder.spendings.spend_camp_key,
                campaign.public_id + adserving.bidder.spendings.string_commission,
                Decimal('0.2')
            )

        update_bidder_spendings()

        channel, message = update_bidder_spendings.rd.publish.call_args[0]
        message = simplejson.loads(message, use_decimal=True)
        assert adserving.bidder.spendings.spend_account_key in message
        assert adserving.bidder.spendings.spend_camp_key in message
        assert adserving.bidder.spendings.spend_strat_key in message
        assert adserving.bidder.spendings.spend_strat_daily_key in message
        assert adserving.bidder.spendings.spend_strat_period_key in message
        # message should have twice that much of entries for campaigns
        assert len(message[adserving.bidder.spendings.spend_camp_key]) == 2 * Campaign.objects.count()
        for account, value in message[adserving.bidder.spendings.spend_account_key].iteritems():
            count = Campaign.objects.filter(account__id_random=account).count()
            # value should be equal to campaign numbers account holds (0.8 for spend, and 0.2 for commission above)
            assert value == count * adserving.bidder.spendings.cast_dbbid_to_CPM(1)
예제 #25
0
파일: __init__.py 프로젝트: sorlandet/code
def append_dollar(decimal_val):
    '''
    Appends dollar sign to the Decimal value (rounded to two places)
    and returns it as a string.
    :rtype: string (i.e '$12.45' or '-$12.45') or None (if value is None)
    '''
    if decimal_val is None:
        return None

    rounded_val = decimal_val.quantize(Decimal('0.01'))

    if rounded_val >= 0:
        return '$%s' % rounded_val

    return '-$%s' % abs(rounded_val)
예제 #26
0
def test_bidding_periods_ratio_not_day_parted(bidding_periods_app):
    '''
    Test if bidding_periods_ratio is 1 for not day parted strategy
    '''

    campaign = Campaign.objects.all().first()
    strategy = Strategy.objects.create(
        name='Strategy Cool',
        campaign=campaign,
        budget_total=12345,
        budget_daily=12345,
        budget_bid_CPM=Decimal('0.2'),
        is_day_parted=False
    )

    assert strategy.bidding_periods_ratio() == 1
예제 #27
0
def setup_bidding_ads(strategy, ads):
    for index, ad in enumerate(ads):
        ad_db = Advert.objects.all()[index]
        if (ad['bid_type'] == 'custom'):
            ad_db._set_custom_bid_CPM(ad['value'])
            ad_db.save()
        elif (ad['bid_type'] == 'custom_parting'):
            for bid in ad['values']:
                period = BiddingPeriod.objects.get(
                    start=bid['start'],
                    end=bid['end']
                )
                AdvertPeriod.objects.create(
                    advert=ad_db,
                    period=period,
                    custom_bid_CPM=Decimal(bid['value'])
                )
예제 #28
0
def db_factory_two_camps(bidding_app):
    """
    Extends bidding_app fixture by adding another campaign. In result database
    has two campaigns.
    """
    campaigns = [
        {'name': 'I\'m a ninja', 'account': 'acc',
         'budget_total': 8000, 'start_UTC': '2013-01-01T00:00',
         'end_UTC': '2013-01-31T00:00',
         'landing_site': 'http://www.google.com/'},
    ]
    strategies = [
        {'name': 'Hello this is ninja', 'campaign': 'I\'m a ninja',
         'budget_total': 12345, 'budget_bid_CPM': Decimal('0.2')},
    ]

    bidding_app.setup_campaigns(campaigns)
    bidding_app.setup_strategies(strategies)
    return bidding_app
예제 #29
0
파일: models.py 프로젝트: sorlandet/code
    def period_budget(self, now):
        '''
        Calculate the period budget based on budget left and period length

        :param datetime now: UTC datetime containing current time
        :returns amount of money to spend in current period
        :rtype Decimal
        '''
        effective_budget = self.budget_left if not self.budget_daily \
            else min(self.budget_daily_left, self.budget_left)

        periods_left = self.periods_left(now)

        if not periods_left:
            return Decimal(0)

        # Period budgets are based on real time so they are ok to
        # be constructed from floats (that leads to 'ugly'
        # decimals).
        return (effective_budget / UnsafeDecimal(periods_left) *
                UnsafeDecimal(self.bidding_periods_ratio()))
예제 #30
0
def bidding_periods_app(app):
    strategies = [
        {'name': 'Hello this is Citrus', 'campaign': 'I\'m a fruit',
         'budget_total': 12345, 'budget_daily': 12345,
         'budget_bid_CPM': Decimal('0.2')}
    ]

    creatives = [
        {'name': 'creative_image_1', 'owner': 'acc', 'width': 300,
         'height': 250, 'image': 'test_creative.jpg'},
        {'name': 'creative_image_2', 'owner': 'acc', 'width': 600,
         'height': 500, 'image': 'test_creative.jpg'},
    ]

    app.setup.setup_landing_pages()
    app.setup.setup_campaigns_running()
    app.setup.setup_strategies(strategies)
    app.setup.setup_creative_images(creatives)

    strategy = app.setup.models['strategy']['Hello this is Citrus']
    creative1 = app.setup.models['creative']['creative_image_1']
    creative2 = app.setup.models['creative']['creative_image_2']

    Advert.objects.create(
        strategy=strategy,
        creative=creative1,
        landing_site=Site.objects.get(
            url='http://www.google.com/',
            owner=strategy.campaign.account)
    )

    Advert.objects.create(
        strategy=strategy,
        creative=creative2,
        landing_site=Site.objects.get(
            url='http://www.google.com/',
            owner=strategy.campaign.account)
    )

    return app