Skip to content

Instantly share code, notes, and snippets.

@Shiroizu
Created May 6, 2024 16:32
Show Gist options
  • Save Shiroizu/700e071d63b603c10ece92873e20e598 to your computer and use it in GitHub Desktop.
Save Shiroizu/700e071d63b603c10ece92873e20e598 to your computer and use it in GitHub Desktop.
import random
# Merges rated songs with new songs while preferring more recent songs
""" Example output
5 new songs
9 rated songs
Weights: [1.0, 0.5, 0.333 ... 0.143, 0.125, 0.111]
Picked 2 rated songs:
['2', '7']
New list:
['2', '1', '2', '7', '3', '4', '5']
7 song ids saved to 'new list.txt'
"""
with open("new song ids.txt") as f:
new_song_ids = f.read().splitlines()
with open("rated songs.txt") as f:
# Most recent first
rated_song_ids = f.read().splitlines()
save_file = "new list.txt"
ratio = 2
# The ratio of new songs compared to rated songs
# Ratio 0.5 is 2 rated songs for every new song, songlist size is tripled.
# Ratio 1 corresponds to equal mix with a doubled songlist size.
# Ratio 4 songlist size is 1.25 of the original.
number_of_songs_to_pick = int(len(new_song_ids) / ratio)
assert number_of_songs_to_pick <= len(rated_song_ids)
def insert_elements_at_nth_index(lst, elements, n):
whole_part = int(n)
fractional_part = n - whole_part
index = 0
for element in elements:
lst.insert(int(index), element)
index += whole_part + 1
index += fractional_part
return lst
def random_with_priority_no_duplicates(lst, num_items, offset=0):
selected_indices = []
available_indices = list(range(len(lst)))
initial_weights = [
round((1 + offset) / (i + 1 + offset), 3) for i in available_indices
]
print(
f"\nWeights: {str(initial_weights[:3])[:-1]} ... {str(initial_weights[-3:])[1:]}"
)
for _ in range(num_items):
weights = [(1 + offset) / (i + 1 + offset) for i in available_indices]
index = random.choices(available_indices, weights=weights, k=1)[0]
selected_indices.append(index)
available_indices.remove(index)
selected_items = [lst[i] for i in selected_indices]
return selected_items
print(f"{len(new_song_ids)} new songs")
print(f"{len(rated_song_ids)} rated songs")
offset = len(rated_song_ids) // 10
selected_items = random_with_priority_no_duplicates(
rated_song_ids, number_of_songs_to_pick, offset=int(offset)
)
print(f"\nPicked {number_of_songs_to_pick} rated songs:")
print(selected_items)
new_list = insert_elements_at_nth_index(new_song_ids, selected_items, ratio)
print("\nNew list:")
print(new_list)
with open(save_file, "w") as f:
f.write("\n".join(new_list))
print(f"\n{len(new_list)} song ids saved to '{save_file}'")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment