def update_cpms(conn, ad_id):
    pipeline = conn.pipeline(True)
    # 获取广告的类型和价格，以及广告包含的所有单词。
    pipeline.hget('type:', ad_id)               
    pipeline.zscore('ad:base_value:', ad_id)    
    pipeline.smembers('terms:' + ad_id)         
    type, base_value, words = pipeline.execute()

    # 判断广告的 eCPM 应该基于点击次数进行计算还是基于动作执行次数进行计算。
    which = 'clicks'                                        
    if type == 'cpa':                                      
        which = 'actions'                                   

    # 根据广告的类型，
    # 获取这类广告的展示次数和点击次数（或者动作执行次数）。
    pipeline.get('type:%s:views:' % type)                   
    pipeline.get('type:%s:%s' % (type, which))              
    type_views, type_clicks = pipeline.execute()            
    # 将广告的点击率或动作执行率重新写入到全局字典里面。
    AVERAGE_PER_1K[type] = (                                        
        1000. * int(type_clicks or '1') / int(type_views or '1'))   

    # 如果正在处理的是一个 CPM 广告，
    # 那么它的 eCPM 已经更新完毕，
    # 无需再做其他处理。
    if type == 'cpm':   
        return          

    view_key = 'views:%s' % ad_id
    click_key = '%s:%s' % (which, ad_id)

    to_ecpm = TO_ECPM[type]

    # 获取广告的展示次数，以及广告的点击次数（或者动作执行次数）。
    pipeline.zscore(view_key, '')                                  
    pipeline.zscore(click_key, '')                                
    ad_views, ad_clicks = pipeline.execute()                      
    # 如果广告还没有被点击过，那么使用已有的 eCPM 。
    if (ad_clicks or 0) < 1:                                       
        ad_ecpm = conn.zscore('idx:ad:value:', ad_id)             
    else:
        # 计算广告的 eCPM 并更新它的价格。
        ad_ecpm = to_ecpm(ad_views or 1, ad_clicks or 0, base_value)
        pipeline.zadd('idx:ad:value:', ad_id, ad_ecpm)              

    for word in words:
        # 获取单词的展示次数和点击次数（或者动作执行次数）。
        pipeline.zscore(view_key, word)                             
        pipeline.zscore(click_key, word)                            
        views, clicks = pipeline.execute()[-2:]                    

        # 如果广告还未被点击过，那么不对 eCPM 进行更新。
        if (clicks or 0) < 1:                                      
            continue                                               

        # 计算单词的 eCPM 。
        word_ecpm = to_ecpm(views or 1, clicks or 0, base_value)   
        # 计算单词的附加值。
        bonus = ad_ecpm - word_ecpm                               
        # 将单词的附加值重新写入到为广告包含的每个单词分别记录附加值的有序集合里面。
        pipeline.zadd('idx:' + word, ad_id, bonus)                 
    pipeline.execute()
# <end id="update_cpms"/>


# 代码清单 7-17
# <start id="slow_job_search"/>
dataset/ETHPy150Open huangz1990/riacn-code/ch07_listing_source.py/update_cpms/swapped operands of `-`