<s> import math <EOL> import re <EOL> import unittest <EOL> import uuid <EOL> import redis <EOL> AVERAGE_PER_1K = { } <EOL> STOP_WORDS = set ( '''<STR_LIT>''' . split ( ) ) <EOL> WORDS_RE = re . compile ( "<STR_LIT>" ) <EOL> def tokenize ( content ) : <EOL> words = set ( ) <EOL> for match in WORDS_RE . finditer ( content . lower ( ) ) : <EOL> word = match . group ( ) . strip ( "<STR_LIT:'>" ) <EOL> if len ( word ) >= <NUM_LIT:2> : <EOL> words . add ( word ) <EOL> return words - STOP_WORDS <EOL> def index_document ( conn , docid , content ) : <EOL> words = tokenize ( content ) <EOL> pipeline = conn . pipeline ( True ) <EOL> for word in words : <EOL> pipeline . sadd ( '<STR_LIT>' + word , docid ) <EOL> return len ( pipeline . execute ( ) ) <EOL> def _set_common ( conn , method , names , ttl = <NUM_LIT:30> , execute = True ) : <EOL> id = str ( uuid . uuid4 ( ) ) <EOL> pipeline = conn . pipeline ( True ) if execute else conn <EOL> names = [ '<STR_LIT>' + name for name in names ] <EOL> getattr ( pipeline , method ) ( '<STR_LIT>' + id , * names ) <EOL> pipeline . expire ( '<STR_LIT>' + id , ttl ) <EOL> if execute : <EOL> pipeline . execute ( ) <EOL> return id <EOL> def intersect ( conn , items , ttl = <NUM_LIT:30> , _execute = True ) : <EOL> return _set_common ( conn , '<STR_LIT>' , items , ttl , _execute ) <EOL> def union ( conn , items , ttl = <NUM_LIT:30> , _execute = True ) : <EOL> return _set_common ( conn , '<STR_LIT>' , items , ttl , _execute ) <EOL> def difference ( conn , items , ttl = <NUM_LIT:30> , _execute = True ) : <EOL> return _set_common ( conn , '<STR_LIT>' , items , ttl , _execute ) <EOL> QUERY_RE = re . compile ( "<STR_LIT>" ) <EOL> def parse ( query ) : <EOL> unwanted = set ( ) <EOL> all = [ ] <EOL> current = set ( ) <EOL> for match in QUERY_RE . finditer ( query . lower ( ) ) : <EOL> word = match . group ( ) <EOL> prefix = word [ : <NUM_LIT:1> ] <EOL> if prefix in '<STR_LIT>' : <EOL> word = word [ <NUM_LIT:1> : ] <EOL> else : <EOL> prefix = None <EOL> word = word . strip ( "<STR_LIT:'>" ) <EOL> if len ( word ) < <NUM_LIT:2> or word in STOP_WORDS : <EOL> continue <EOL> if prefix == '<STR_LIT:->' : <EOL> unwanted . add ( word ) <EOL> continue <EOL> if current and not prefix : <EOL> all . append ( list ( current ) ) <EOL> current = set ( ) <EOL> current . add ( word ) <EOL> if current : <EOL> all . append ( list ( current ) ) <EOL> return all , list ( unwanted ) <EOL> def parse_and_search ( conn , query , ttl = <NUM_LIT:30> ) : <EOL> all , unwanted = parse ( query ) <EOL> if not all : <EOL> return None <EOL> to_intersect = [ ] <EOL> for syn in all : <EOL> if len ( syn ) > <NUM_LIT:1> : <EOL> to_intersect . append ( union ( conn , syn , ttl = ttl ) ) <EOL> else : <EOL> to_intersect . append ( syn [ <NUM_LIT:0> ] ) <EOL> if len ( to_intersect ) > <NUM_LIT:1> : <EOL> intersect_result = intersect ( conn , to_intersect , ttl = ttl ) <EOL> else : <EOL> intersect_result = to_intersect [ <NUM_LIT:0> ] <EOL> if unwanted : <EOL> unwanted . insert ( <NUM_LIT:0> , intersect_result ) <EOL> return difference ( conn , unwanted , ttl = ttl ) <EOL> return intersect_result <EOL> def search_and_sort ( conn , query , id = None , ttl = <NUM_LIT> , sort = "<STR_LIT>" , <EOL> start = <NUM_LIT:0> , num = <NUM_LIT:20> ) : <EOL> desc = sort . startswith ( '<STR_LIT:->' ) <EOL> sort = sort . lstrip ( '<STR_LIT:->' ) <EOL> by = "<STR_LIT>" + sort <EOL> alpha = sort not in ( '<STR_LIT>' , '<STR_LIT:id>' , '<STR_LIT>' ) <EOL> if id and not conn . expire ( id , ttl ) : <EOL> id = None <EOL> if not id : <EOL> id = parse_and_search ( conn , query , ttl = ttl ) <EOL> pipeline = conn . pipeline ( True ) <EOL> pipeline . scard ( '<STR_LIT>' + id ) <EOL> pipeline . sort ( '<STR_LIT>' + id , by = by , alpha = alpha , <EOL> desc = desc , start = start , num = num ) <EOL> results = pipeline . execute ( ) <EOL> return results [ <NUM_LIT:0> ] , results [ <NUM_LIT:1> ] , id <EOL> def search_and_zsort ( conn , query , id = None , ttl = <NUM_LIT> , update = <NUM_LIT:1> , vote = <NUM_LIT:0> , <EOL> start = <NUM_LIT:0> , num = <NUM_LIT:20> , desc = True ) : <EOL> if id and not conn . expire ( id , ttl ) : <EOL> id = None <EOL> if not id : <EOL> id = parse_and_search ( conn , query , ttl = ttl ) <EOL> scored_search = { <EOL> id : <NUM_LIT:0> , <EOL> '<STR_LIT>' : update , <EOL> '<STR_LIT>' : vote <EOL> } <EOL> id = zintersect ( conn , scored_search , ttl ) <EOL> pipeline = conn . pipeline ( True ) <EOL> pipeline . zcard ( '<STR_LIT>' + id ) <EOL> if desc : <EOL> pipeline . zrevrange ( '<STR_LIT>' + id , start , start + num - <NUM_LIT:1> ) <EOL> else : <EOL> pipeline . zrange ( '<STR_LIT>' + id , start , start + num - <NUM_LIT:1> ) <EOL> results = pipeline . execute ( ) <EOL> return results [ <NUM_LIT:0> ] , results [ <NUM_LIT:1> ] , id <EOL> def _zset_common ( conn , method , scores , ttl = <NUM_LIT:30> , ** kw ) : <EOL> id = str ( uuid . uuid4 ( ) ) <EOL> execute = kw . pop ( '<STR_LIT>' , True ) <EOL> pipeline = conn . pipeline ( True ) if execute else conn <EOL> for key in scores . keys ( ) : <EOL> scores [ '<STR_LIT>' + key ] = scores . pop ( key ) <EOL> getattr ( pipeline , method ) ( '<STR_LIT>' + id , scores , ** kw ) <EOL> pipeline . expire ( '<STR_LIT>' + id , ttl ) <EOL> if execute : <EOL> pipeline . execute ( ) <EOL> return id <EOL> def zintersect ( conn , items , ttl = <NUM_LIT:30> , ** kw ) : <EOL> return _zset_common ( conn , '<STR_LIT>' , dict ( items ) , ttl , ** kw ) <EOL> def zunion ( conn , items , ttl = <NUM_LIT:30> , ** kw ) : <EOL> return _zset_common ( conn , '<STR_LIT>' , dict ( items ) , ttl , ** kw ) <EOL> def string_to_score ( string , ignore_case = False ) : <EOL> if ignore_case : <EOL> string = string . lower ( ) <EOL> pieces = map ( ord , string [ : <NUM_LIT:6> ] ) <EOL> while len ( pieces ) < <NUM_LIT:6> : <EOL> pieces . append ( - <NUM_LIT:1> ) <EOL> score = <NUM_LIT:0> <EOL> for piece in pieces : <EOL> score = score * <NUM_LIT> + piece + <NUM_LIT:1> <EOL> return score * <NUM_LIT:2> + ( len ( string ) > <NUM_LIT:6> ) <EOL> def to_char_map ( set ) : <EOL> out = { } <EOL> for pos , val in enumerate ( sorted ( set ) ) : <EOL> out [ val ] = pos - <NUM_LIT:1> <EOL> return out <EOL> LOWER = to_char_map ( set ( [ - <NUM_LIT:1> ] ) | set ( xrange ( ord ( '<STR_LIT:a>' ) , ord ( '<STR_LIT:z>' ) + <NUM_LIT:1> ) ) ) <EOL> ALPHA = to_char_map ( set ( LOWER ) | set ( xrange ( ord ( '<STR_LIT:A>' ) , ord ( '<STR_LIT>' ) + <NUM_LIT:1> ) ) ) <EOL> LOWER_NUMERIC = to_char_map ( set ( LOWER ) | set ( xrange ( ord ( '<STR_LIT:0>' ) , ord ( '<STR_LIT>' ) + <NUM_LIT:1> ) ) ) <EOL> ALPHA_NUMERIC = to_char_map ( set ( LOWER_NUMERIC ) | set ( ALPHA ) ) <EOL> def string_to_score_generic ( string , mapping ) : <EOL> length = int ( <NUM_LIT> / math . log ( len ( mapping ) , <NUM_LIT:2> ) ) <EOL> pieces = map ( ord , string [ : length ] ) <EOL> while len ( pieces ) < length : <EOL> pieces . append ( - <NUM_LIT:1> ) <EOL> score = <NUM_LIT:0> <EOL> for piece in pieces : <EOL> value = mapping [ piece ] <EOL> score = score * len ( mapping ) + value + <NUM_LIT:1> <EOL> return score * <NUM_LIT:2> + ( len ( string ) > length ) <EOL> def zadd_string ( conn , name , * args , ** kwargs ) : <EOL> pieces = list ( args ) <EOL> for piece in kwargs . iteritems ( ) : <EOL> pieces . extend ( piece ) <EOL> for i , v in enumerate ( pieces ) : <EOL> if i & <NUM_LIT:1> : <EOL> pieces [ i ] = string_to_score ( v ) <EOL> return conn . zadd ( name , * pieces ) <EOL> def cpc_to_ecpm ( views , clicks , cpc ) : <EOL> return <NUM_LIT> * cpc * clicks / views <EOL> def cpa_to_ecpm ( views , actions , cpa ) : <EOL> return <NUM_LIT> * cpa * actions / views <EOL> TO_ECPM = { <EOL> '<STR_LIT>' : cpc_to_ecpm , <EOL> '<STR_LIT>' : cpa_to_ecpm , <EOL> '<STR_LIT>' : lambda * args : args [ - <NUM_LIT:1> ] , <EOL> } <EOL> def index_ad ( conn , id , locations , content , type , value ) : <EOL> pipeline = conn . pipeline ( True ) <EOL> for location in locations : <EOL> pipeline . sadd ( '<STR_LIT>' + location , id ) <EOL> words = tokenize ( content ) <EOL> for word in tokenize ( content ) : <EOL> pipeline . zadd ( '<STR_LIT>' + word , id , <NUM_LIT:0> ) <EOL> rvalue = TO_ECPM [ type ] ( <EOL> <NUM_LIT:1000> , AVERAGE_PER_1K . get ( type , <NUM_LIT:1> ) , value ) <EOL> pipeline . hset ( '<STR_LIT>' , id , type ) <EOL> pipeline . zadd ( '<STR_LIT>' , id , rvalue ) <EOL> pipeline . zadd ( '<STR_LIT>' , id , value ) <EOL> pipeline . sadd ( '<STR_LIT>' + id , * list ( words ) ) <EOL> pipeline . execute ( ) <EOL> def target_ads ( conn , locations , content ) : <EOL> pipeline = conn . pipeline ( True ) <EOL> matched_ads , base_ecpm = match_location ( pipeline , locations ) <EOL> words , targeted_ads = finish_scoring ( <EOL> pipeline , matched_ads , base_ecpm , content ) <EOL> pipeline . incr ( '<STR_LIT>' ) <EOL> pipeline . zrevrange ( '<STR_LIT>' + targeted_ads , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> target_id , targeted_ad = pipeline . execute ( ) [ - <NUM_LIT:2> : ] <EOL> if not targeted_ad : <EOL> return None , None <EOL> ad_id = targeted_ad [ <NUM_LIT:0> ] <EOL> record_targeting_result ( conn , target_id , ad_id , words ) <EOL> return target_id , ad_id <EOL> def match_location ( pipe , locations ) : <EOL> required = [ '<STR_LIT>' + loc for loc in locations ] <EOL> matched_ads = union ( pipe , required , ttl = <NUM_LIT> , _execute = False ) <EOL> return matched_ads , zintersect ( pipe , <EOL> { matched_ads : <NUM_LIT:0> , '<STR_LIT>' : <NUM_LIT:1> } , _execute = False ) <EOL> def finish_scoring ( pipe , matched , base , content ) : <EOL> bonus_ecpm = { } <EOL> words = tokenize ( content ) <EOL> for word in words : <EOL> word_bonus = zintersect ( <EOL> pipe , { matched : <NUM_LIT:0> , word : <NUM_LIT:1> } , _execute = False ) <EOL> bonus_ecpm [ word_bonus ] = <NUM_LIT:1> <EOL> if bonus_ecpm : <EOL> minimum = zunion ( <EOL> pipe , bonus_ecpm , aggregate = '<STR_LIT>' , _execute = False ) <EOL> maximum = zunion ( <EOL> pipe , bonus_ecpm , aggregate = '<STR_LIT>' , _execute = False ) <EOL> return words , zunion ( <EOL> pipe , { base : <NUM_LIT:1> , minimum : <NUM_LIT> , maximum : <NUM_LIT> } , _execute = False ) <EOL> return words , base <EOL> def record_targeting_result ( conn , target_id , ad_id , words ) : <EOL> pipeline = conn . pipeline ( True ) <EOL> terms = conn . smembers ( '<STR_LIT>' + ad_id ) <EOL> matched = list ( words & terms ) <EOL> if matched : <EOL> matched_key = '<STR_LIT>' % target_id <EOL> pipeline . sadd ( matched_key , * matched ) <EOL> pipeline . expire ( matched_key , <NUM_LIT> ) <EOL> type = conn . hget ( '<STR_LIT>' , ad_id ) <EOL> pipeline . incr ( '<STR_LIT>' % type ) <EOL> for word in matched : <EOL> pipeline . zincrby ( '<STR_LIT>' % ad_id , word ) <EOL> pipeline . zincrby ( '<STR_LIT>' % ad_id , '<STR_LIT>' ) <EOL> if not pipeline . execute ( ) [ - <NUM_LIT:1> ] % <NUM_LIT:100> : <EOL> update_cpms ( conn , ad_id ) <EOL> def record_click ( conn , target_id , ad_id , action = False ) : <EOL> pipeline = conn . pipeline ( True ) <EOL> click_key = '<STR_LIT>' % ad_id <EOL> match_key = '<STR_LIT>' % target_id <EOL> type = conn . hget ( '<STR_LIT>' , ad_id ) <EOL> if type == '<STR_LIT>' : <EOL> pipeline . expire ( match_key , <NUM_LIT> ) <EOL> if action : <EOL> click_key = '<STR_LIT>' % ad_id <EOL> if action and type == '<STR_LIT>' : <EOL> pipeline . incr ( '<STR_LIT>' % type ) <EOL> else : <EOL> pipeline . incr ( '<STR_LIT>' % type ) <EOL> matched = list ( conn . smembers ( match_key ) ) <EOL> matched . append ( '<STR_LIT>' ) <EOL> for word in matched : <EOL> pipeline . zincrby ( click_key , word ) <EOL> pipeline . execute ( ) <EOL> update_cpms ( conn , ad_id ) <EOL> def update_cpms ( conn , ad_id ) : <EOL> pipeline = conn . pipeline ( True ) <EOL> pipeline . hget ( '<STR_LIT>' , ad_id ) <EOL> pipeline . zscore ( '<STR_LIT>' , ad_id ) <EOL> pipeline . smembers ( '<STR_LIT>' + ad_id ) <EOL> type , base_value , words = pipeline . execute ( ) <EOL> which = '<STR_LIT>' <EOL> if type == '<STR_LIT>' : <EOL> which = '<STR_LIT>' <EOL> pipeline . get ( '<STR_LIT>' % type ) <EOL> pipeline . get ( '<STR_LIT>' % ( type , which ) ) <EOL> type_views , type_clicks = pipeline . execute ( ) <EOL> AVERAGE_PER_1K [ type ] = ( <EOL> <NUM_LIT> * int ( type_clicks or '<STR_LIT:1>' ) / int ( type_views or '<STR_LIT:1>' ) ) <EOL> if type == '<STR_LIT>' : <EOL> return <EOL> view_key = '<STR_LIT>' % ad_id <EOL> click_key = '<STR_LIT>' % ( which , ad_id ) <EOL> to_ecpm = TO_ECPM [ type ] <EOL> pipeline . zscore ( view_key , '<STR_LIT>' ) <EOL> pipeline . zscore ( click_key , '<STR_LIT>' ) <EOL> ad_views , ad_clicks = pipeline . execute ( ) <EOL> if ( ad_clicks or <NUM_LIT:0> ) < <NUM_LIT:1> : <EOL> ad_ecpm = conn . zscore ( '<STR_LIT>' , ad_id ) <EOL> else : <EOL> ad_ecpm = to_ecpm ( ad_views or <NUM_LIT:1> , ad_clicks or <NUM_LIT:0> , base_value ) <EOL> pipeline . zadd ( '<STR_LIT>' , ad_id , ad_ecpm ) <EOL> for word in words : <EOL> pipeline . zscore ( view_key , word ) <EOL> pipeline . zscore ( click_key , word ) <EOL> views , clicks = pipeline . execute ( ) [ - <NUM_LIT:2> : ] <EOL> if ( clicks or <NUM_LIT:0> ) < <NUM_LIT:1> : <EOL> continue <EOL> word_ecpm = to_ecpm ( views or <NUM_LIT:1> , clicks or <NUM_LIT:0> , base_value ) <EOL> bonus = word_ecpm - ad_ecpm <EOL> pipeline . zadd ( '<STR_LIT>' + word , ad_id , bonus ) <EOL> pipeline . execute ( ) <EOL> def add_job ( conn , job_id , required_skills ) : <EOL> conn . sadd ( '<STR_LIT>' + job_id , * required_skills ) <EOL> def is_qualified ( conn , job_id , candidate_skills ) : <EOL> temp = str ( uuid . uuid4 ( ) ) <EOL> pipeline = conn . pipeline ( True ) <EOL> pipeline . sadd ( temp , * candidate_skills ) <EOL> pipeline . expire ( temp , <NUM_LIT:5> ) <EOL> pipeline . sdiff ( '<STR_LIT>' + job_id , temp ) <EOL> return not pipeline . execute ( ) [ - <NUM_LIT:1> ] <EOL> def index_job ( conn , job_id , skills ) : <EOL> pipeline = conn . pipeline ( True ) <EOL> for skill in skills : <EOL> pipeline . sadd ( '<STR_LIT>' + skill , job_id ) <EOL> pipeline . zadd ( '<STR_LIT>' , job_id , len ( set ( skills ) ) ) <EOL> pipeline . execute ( ) <EOL> def find_jobs ( conn , candidate_skills ) : <EOL> skills = { } <EOL> for skill in set ( candidate_skills ) : <EOL> skills [ '<STR_LIT>' + skill ] = <NUM_LIT:1> <EOL> job_scores = zunion ( conn , skills ) <EOL> final_result = zintersect ( <EOL> conn , { job_scores : - <NUM_LIT:1> , '<STR_LIT>' : <NUM_LIT:1> } ) <EOL> return conn . zrangebyscore ( '<STR_LIT>' + final_result , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> SKILL_LEVEL_LIMIT = <NUM_LIT:2> <EOL> def index_job_levels ( conn , job_id , skill_levels ) : <EOL> total_skills = len ( set ( skill for skill , level in skill_levels ) ) <EOL> pipeline = conn . pipeline ( True ) <EOL> for skill , level in skill_levels : <EOL> level = min ( level , SKILL_LEVEL_LIMIT ) <EOL> for wlevel in xrange ( level , SKILL_LEVEL_LIMIT + <NUM_LIT:1> ) : <EOL> pipeline . sadd ( '<STR_LIT>' % ( skill , wlevel ) , job_id ) <EOL> pipeline . zadd ( '<STR_LIT>' , job_id , total_skills ) <EOL> pipeline . execute ( ) <EOL> def search_job_levels ( conn , skill_levels ) : <EOL> skills = { } <EOL> for skill , level in skill_levels : <EOL> level = min ( level , SKILL_LEVEL_LIMIT ) <EOL> for wlevel in xrange ( level , SKILL_LEVEL_LIMIT + <NUM_LIT:1> ) : <EOL> skills [ '<STR_LIT>' % ( skill , wlevel ) ] = <NUM_LIT:1> <EOL> job_scores = zunion ( conn , skills ) <EOL> final_result = zintersect ( conn , { job_scores : - <NUM_LIT:1> , '<STR_LIT>' : <NUM_LIT:1> } ) <EOL> return conn . zrangebyscore ( '<STR_LIT>' + final_result , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> def index_job_years ( conn , job_id , skill_years ) : <EOL> total_skills = len ( set ( skill for skill , level in skill_years ) ) <EOL> pipeline = conn . pipeline ( True ) <EOL> for skill , years in skill_years : <EOL> pipeline . zadd ( <EOL> '<STR_LIT>' % skill , job_id , max ( years , <NUM_LIT:0> ) ) <EOL> pipeline . sadd ( '<STR_LIT>' , job_id ) <EOL> pipeline . zadd ( '<STR_LIT>' , job_id , total_skills ) <EOL> def search_job_years ( conn , skill_years ) : <EOL> skill_years = dict ( skill_years ) <EOL> pipeline = conn . pipeline ( True ) <EOL> union = [ ] <EOL> for skill , years in skill_years . iteritems ( ) : <EOL> sub_result = zintersect ( pipeline , <EOL> { '<STR_LIT>' : - years , '<STR_LIT>' % skill : <NUM_LIT:1> } , _execute = False ) <EOL> pipeline . zremrangebyscore ( '<STR_LIT>' + sub_result , '<STR_LIT>' , '<STR_LIT>' ) <EOL> union . append ( <EOL> zintersect ( pipeline , { '<STR_LIT>' : <NUM_LIT:1> , sub_result : <NUM_LIT:0> } ) , _execute = False ) <EOL> job_scores = zunion ( pipeline , dict ( ( key , <NUM_LIT:1> ) for key in union ) , _execute = False ) <EOL> final_result = zintersect ( pipeline , { job_scores : - <NUM_LIT:1> , '<STR_LIT>' : <NUM_LIT:1> } , _execute = False ) <EOL> pipeline . zrange ( '<STR_LIT>' + final_result , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> return pipeline . execute ( ) [ - <NUM_LIT:1> ] <EOL> class TestCh07 ( unittest . TestCase ) : <EOL> content = '<STR_LIT>' <EOL> def setUp ( self ) : <EOL> self . conn = redis . Redis ( db = <NUM_LIT:15> ) <EOL> self . conn . flushdb ( ) <EOL> def tearDown ( self ) : <EOL> self . conn . flushdb ( ) <EOL> def test_index_document ( self ) : <EOL> print "<STR_LIT>" <EOL> tokens = tokenize ( self . content ) <EOL> print "<STR_LIT>" , tokens <EOL> self . assertTrue ( tokens ) <EOL> print "<STR_LIT>" <EOL> r = index_document ( self . conn , '<STR_LIT:test>' , self . content ) <EOL> self . assertEquals ( r , len ( tokens ) ) <EOL> for t in tokens : <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + t ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> def test_set_operations ( self ) : <EOL> index_document ( self . conn , '<STR_LIT:test>' , self . content ) <EOL> r = intersect ( self . conn , [ '<STR_LIT:content>' , '<STR_LIT>' ] ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> r = intersect ( self . conn , [ '<STR_LIT:content>' , '<STR_LIT>' ] ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( ) ) <EOL> r = union ( self . conn , [ '<STR_LIT:content>' , '<STR_LIT>' ] ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> r = difference ( self . conn , [ '<STR_LIT:content>' , '<STR_LIT>' ] ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> r = difference ( self . conn , [ '<STR_LIT:content>' , '<STR_LIT>' ] ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( ) ) <EOL> def test_parse_query ( self ) : <EOL> query = '<STR_LIT>' <EOL> self . assertEquals ( parse ( query ) , ( [ [ x ] for x in query . split ( ) ] , [ ] ) ) <EOL> query = '<STR_LIT>' <EOL> self . assertEquals ( parse ( query ) , ( [ [ '<STR_LIT:test>' , '<STR_LIT>' ] , [ '<STR_LIT>' ] ] , [ '<STR_LIT>' ] ) ) <EOL> def test_parse_and_search ( self ) : <EOL> print "<STR_LIT>" <EOL> index_document ( self . conn , '<STR_LIT:test>' , self . content ) <EOL> r = parse_and_search ( self . conn , '<STR_LIT:content>' ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> r = parse_and_search ( self . conn , '<STR_LIT>' ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> r = parse_and_search ( self . conn , '<STR_LIT>' ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> r = parse_and_search ( self . conn , '<STR_LIT>' ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> r = parse_and_search ( self . conn , '<STR_LIT>' ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( ) ) <EOL> r = parse_and_search ( self . conn , '<STR_LIT>' ) <EOL> self . assertEquals ( self . conn . smembers ( '<STR_LIT>' + r ) , set ( [ '<STR_LIT:test>' ] ) ) <EOL> print "<STR_LIT>" <EOL> def test_search_with_sort ( self ) : <EOL> print "<STR_LIT>" <EOL> index_document ( self . conn , '<STR_LIT:test>' , self . content ) <EOL> index_document ( self . conn , '<STR_LIT>' , self . content ) <EOL> self . conn . hmset ( '<STR_LIT>' , { '<STR_LIT>' : <NUM_LIT> , '<STR_LIT:id>' : <NUM_LIT:10> } ) <EOL> self . conn . hmset ( '<STR_LIT>' , { '<STR_LIT>' : <NUM_LIT> , '<STR_LIT:id>' : <NUM_LIT:1> } ) <EOL> r = search_and_sort ( self . conn , "<STR_LIT:content>" ) <EOL> self . assertEquals ( r [ <NUM_LIT:1> ] , [ '<STR_LIT>' , '<STR_LIT:test>' ] ) <EOL> r = search_and_sort ( self . conn , "<STR_LIT:content>" , sort = '<STR_LIT>' ) <EOL> self . assertEquals ( r [ <NUM_LIT:1> ] , [ '<STR_LIT:test>' , '<STR_LIT>' ] ) <EOL> print "<STR_LIT>" <EOL> def test_search_with_zsort ( self ) : <EOL> print "<STR_LIT>" <EOL> index_document ( self . conn , '<STR_LIT:test>' , self . content ) <EOL> index_document ( self . conn , '<STR_LIT>' , self . content ) <EOL> self . conn . zadd ( '<STR_LIT>' , '<STR_LIT:test>' , <NUM_LIT> , '<STR_LIT>' , <NUM_LIT> ) <EOL> self . conn . zadd ( '<STR_LIT>' , '<STR_LIT:test>' , <NUM_LIT:10> , '<STR_LIT>' , <NUM_LIT:1> ) <EOL> r = search_and_zsort ( self . conn , "<STR_LIT:content>" , desc = False ) <EOL> self . assertEquals ( r [ <NUM_LIT:1> ] , [ '<STR_LIT:test>' , '<STR_LIT>' ] ) <EOL> r = search_and_zsort ( self . conn , "<STR_LIT:content>" , update = <NUM_LIT:0> , vote = <NUM_LIT:1> , desc = False ) <EOL> self . assertEquals ( r [ <NUM_LIT:1> ] , [ '<STR_LIT>' , '<STR_LIT:test>' ] ) <EOL> print "<STR_LIT>" <EOL> def test_string_to_score ( self ) : <EOL> words = '<STR_LIT>' . split ( ) <EOL> pairs = [ ( word , string_to_score ( word ) ) for word in words ] <EOL> pairs2 = list ( pairs ) <EOL> pairs . sort ( ) <EOL> pairs2 . sort ( key = lambda x : x [ <NUM_LIT:1> ] ) <EOL> self . assertEquals ( pairs , pairs2 ) <EOL> words = '<STR_LIT>' . split ( ) <EOL> pairs = [ ( word , string_to_score_generic ( word , LOWER ) ) for word in words ] <EOL> pairs2 = list ( pairs ) <EOL> pairs . sort ( ) <EOL> pairs2 . sort ( key = lambda x : x [ <NUM_LIT:1> ] ) <EOL> self . assertEquals ( pairs , pairs2 ) <EOL> zadd_string ( self . conn , '<STR_LIT:key>' , '<STR_LIT:test>' , '<STR_LIT:value>' , test2 = '<STR_LIT>' ) <EOL> self . assertTrue ( self . conn . zscore ( '<STR_LIT:key>' , '<STR_LIT:test>' ) , string_to_score ( '<STR_LIT:value>' ) ) <EOL> self . assertTrue ( self . conn . zscore ( '<STR_LIT:key>' , '<STR_LIT>' ) , string_to_score ( '<STR_LIT>' ) ) <EOL> def test_index_and_target_ads ( self ) : <EOL> index_ad ( self . conn , '<STR_LIT:1>' , [ '<STR_LIT>' , '<STR_LIT>' ] , self . content , '<STR_LIT>' , <NUM_LIT> ) <EOL> index_ad ( self . conn , '<STR_LIT:2>' , [ '<STR_LIT>' , '<STR_LIT>' ] , self . content + '<STR_LIT>' , '<STR_LIT>' , <NUM_LIT> ) <EOL> for i in xrange ( <NUM_LIT:100> ) : <EOL> ro = target_ads ( self . conn , [ '<STR_LIT>' ] , self . content ) <EOL> self . assertEquals ( ro [ <NUM_LIT:1> ] , '<STR_LIT:1>' ) <EOL> r = target_ads ( self . conn , [ '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> self . assertEquals ( r [ <NUM_LIT:1> ] , '<STR_LIT:2>' ) <EOL> self . assertEquals ( self . conn . zrange ( '<STR_LIT>' , <NUM_LIT:0> , - <NUM_LIT:1> , withscores = True ) , [ ( '<STR_LIT:2>' , <NUM_LIT> ) , ( '<STR_LIT:1>' , <NUM_LIT> ) ] ) <EOL> self . assertEquals ( self . conn . zrange ( '<STR_LIT>' , <NUM_LIT:0> , - <NUM_LIT:1> , withscores = True ) , [ ( '<STR_LIT:2>' , <NUM_LIT> ) , ( '<STR_LIT:1>' , <NUM_LIT> ) ] ) <EOL> record_click ( self . conn , ro [ <NUM_LIT:0> ] , ro [ <NUM_LIT:1> ] ) <EOL> self . assertEquals ( self . conn . zrange ( '<STR_LIT>' , <NUM_LIT:0> , - <NUM_LIT:1> , withscores = True ) , [ ( '<STR_LIT:2>' , <NUM_LIT> ) , ( '<STR_LIT:1>' , <NUM_LIT> ) ] ) <EOL> self . assertEquals ( self . conn . zrange ( '<STR_LIT>' , <NUM_LIT:0> , - <NUM_LIT:1> , withscores = True ) , [ ( '<STR_LIT:2>' , <NUM_LIT> ) , ( '<STR_LIT:1>' , <NUM_LIT> ) ] ) <EOL> def test_is_qualified_for_job ( self ) : <EOL> add_job ( self . conn , '<STR_LIT:test>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> self . assertTrue ( is_qualified ( self . conn , '<STR_LIT:test>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) ) <EOL> self . assertFalse ( is_qualified ( self . conn , '<STR_LIT:test>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) ) <EOL> def test_index_and_find_jobs ( self ) : <EOL> index_job ( self . conn , '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> index_job ( self . conn , '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> index_job ( self . conn , '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> self . assertEquals ( find_jobs ( self . conn , [ '<STR_LIT>' ] ) , [ ] ) <EOL> self . assertEquals ( find_jobs ( self . conn , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , [ '<STR_LIT>' ] ) <EOL> self . assertEquals ( find_jobs ( self . conn , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , [ '<STR_LIT>' ] ) <EOL> self . assertEquals ( find_jobs ( self . conn , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> unittest . main ( ) </s>
