Created
May 6, 2024 16:32
-
-
Save Shiroizu/700e071d63b603c10ece92873e20e598 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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