Skip to content

Instantly share code, notes, and snippets.

@Rabbonos
Last active February 9, 2025 13:43
Show Gist options
  • Save Rabbonos/1fb29706cc370465704f66ede7c968d4 to your computer and use it in GitHub Desktop.
Save Rabbonos/1fb29706cc370465704f66ede7c968d4 to your computer and use it in GitHub Desktop.
from pprint import pprint
import random
import math
TIMESTAMPS_COUNT = 50000
PROBABILITY_SCORE_CHANGED = 0.0001
PROBABILITY_HOME_SCORE = 0.45
OFFSET_MAX_STEP = 3
INITIAL_STAMP = {
"offset": 0,
"score": {
"home": 0,
"away": 0
}
}
def generate_stamp(previous_value):
score_changed = random.random() > 1 - PROBABILITY_SCORE_CHANGED
home_score_change = 1 if score_changed and random.random() > 1 - \
PROBABILITY_HOME_SCORE else 0
away_score_change = 1 if score_changed and not home_score_change else 0
offset_change = math.floor(random.random() * OFFSET_MAX_STEP) + 1
return {
"offset": previous_value["offset"] + offset_change,
"score": {
"home": previous_value["score"]["home"] + home_score_change,
"away": previous_value["score"]["away"] + away_score_change
}
}
def generate_game():
stamps = [INITIAL_STAMP, ]
current_stamp = INITIAL_STAMP
for _ in range(TIMESTAMPS_COUNT):
current_stamp = generate_stamp(current_stamp)
stamps.append(current_stamp)
return stamps
game_stamps = generate_game()
def get_score(game_stamps, offset):
'''
Takes list of game's stamps and time offset for which returns the scores for the home and away teams.
Please pay attention to that for some offsets the game_stamps list may not contain scores.
'''
#as this is a test task, I decided to show all my solutions:
#bad solution
# for game in game_stamps:
# if game['offset'] == offset:
# home,away = game['score']['home'], game['score']['away']
# return home,away
#slightly better solution (still bad)
# game = [game for game in game_stamps if game.get('offset') == offset ]
# if len(game) > 0:
# game=game[0]
# home, away = game['score']['home'], game['score']['away']
# return home, away
# else:
# ValueError(f'Value for {offset} was not found!')
#a slightly better solution (but still bad)
# last_offset = game_stamps[-1]['offset']
# if last_offset<offset:
# raise ValueError(f"Offset '{offset}' is ahead of the last offset")
# location = len(game_stamps)//2
# while location>0:
# if game_stamps[location]['offset'] == offset:
# if game_stamps[location].get('score'):
# home, away = game_stamps[location]['score']['home'], game_stamps[location]['score']['away']
# return home, away
# else:
# raise ValueError(f'Offset {offset} was not found')
# elif game_stamps[location]['offset'] > offset:
# game_stamps = game_stamps[0:location]
# else:
# last=len(game_stamps)+1
# game_stamps = game_stamps[location:last]
# location = len(game_stamps)//2
# if location == 0:
# if game_stamps[location].get('score'):
# home, away = game_stamps[location]['score']['home'], game_stamps[location]['score']['away']
# return home, away
# else:
# raise ValueError(f'Offset {offset} was not found')
# raise ValueError(f'Offset {offset} was not found')
#the last solution, the best one
#edge case
if len(game_stamps)==0 or game_stamps[-1]['offset']<offset or offset<0:
raise ValueError(f"Offset '{offset}' is ahead of the last offset")
low_end, high_end = 0,len(game_stamps)-1
while low_end <=high_end:
middle = (low_end+high_end) //2
if game_stamps[middle]['offset'] == offset:
if game_stamps[middle].get('score'):
home, away = game_stamps[middle]['score']['home'], game_stamps[middle]['score']['away']
if isinstance(home, int) and isinstance(away, int):
return home, away
raise ValueError(f'Offset {offset} was not found')
elif game_stamps[middle]['offset']>offset:
high_end = middle-1
else:
low_end = middle+1
raise ValueError(f'Offset {offset} was not found')
if __name__=='__main__':
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment