Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7d6cd7b
implemented better __repr__
Oct 11, 2023
41e614f
Game now shows what you got correct and what you got wrong
Oct 11, 2023
61c3fdc
displaying sessions best score
Oct 11, 2023
5d743f5
guess function no longer needed
Oct 12, 2023
6f76004
changed how correct guess display is spaced
Oct 12, 2023
d5165ed
added function to create colored text
Oct 12, 2023
abf7302
showing both correct and incorrect guesses
Oct 12, 2023
a557299
abstracted away some information from GameState to its own class Level
Oct 12, 2023
71ba73f
showing 4 lines of the song translated into emojis instead of song name
Oct 12, 2023
1a74d66
Merge branch 'main' into game_v2
Oct 12, 2023
bde4f0c
added repr for Lyrics class
Oct 13, 2023
fd79ba6
made game_state into dataclass and removed repr
Oct 13, 2023
bb35af0
Added support for the new json data.
Oct 14, 2023
b658e4e
showing the original lyrics when a guess is made
Oct 14, 2023
d2724ad
fixed bug where get songs was returning duplicate songs
Oct 14, 2023
2cb3323
fixed bug where result was showing the next level not current one
Oct 14, 2023
85ee90e
simplified get_songs function in DataManager
Oct 14, 2023
8d95ccc
Merge branch 'main' into game_v2
Oct 17, 2023
29dcee6
first working version on database integration
Oct 17, 2023
9d72787
removed unused functions
Oct 18, 2023
66cc8fb
add pymongo, fix problem with requirement
aguschin Oct 18, 2023
1718ac5
merge main into this
aguschin Oct 18, 2023
ff61ea0
store top_300_spotify_translated.json in git
aguschin Oct 18, 2023
97d9f7d
improved game visuals
Oct 18, 2023
a189a97
Merge branch 'main' into game_v2
Oct 18, 2023
dcd87c7
Merge branch 'game_v2' of https://github.com/aguschin/lyrics2emoji in…
Oct 18, 2023
5d93ae4
Merge branch 'main' into game_v2
aguschin Oct 19, 2023
8877fe1
use cleaned lyrics
aguschin Oct 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

Expand Down Expand Up @@ -158,3 +157,7 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/

#streamlit
.streamlit
.streamlit/secrets.toml
2 changes: 0 additions & 2 deletions data/sample_data/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@
/lyrics_vectorized.npy
/top_300_spotify.json
/top_10_spotify_translated.json
/top_300_spotify_translated.json
/top_300_spotify_with_embeddings.json
/top_300_spotify_cleaned_and_translated.json
2,249 changes: 2,249 additions & 0 deletions data/sample_data/top_300_spotify_cleaned_and_translated.json

Large diffs are not rendered by default.

This file was deleted.

1,928 changes: 1,928 additions & 0 deletions data/sample_data/top_300_spotify_translated.json

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions data/sample_data/top_300_spotify_translated.json.dvc

This file was deleted.

Binary file modified requirements.txt
Binary file not shown.
107 changes: 107 additions & 0 deletions src/game_data_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from __future__ import annotations

import json
import re
from dataclasses import dataclass
from random import choice
from random import randint

import streamlit as st

INVALID_PATTERN: str = r"\([^)]*\)"
JSON_DATA: str = "data/sample_data/top_300_spotify_cleaned_and_translated.json"


@dataclass(slots=True, init=False, repr=False)
class Lyrics:
bars: list[str]
translated_bars: list[str]

def __init__(self, lyrics: str, translated_lyrics: str) -> None:
self.bars: list[str] = []
self.translated_bars: list[str] = []
self._load_lyrics(lyrics, translated_lyrics)

def _load_lyrics(self, lyrics: str, translated_lyrics: str) -> None:
for bar in translated_lyrics.split("\n"):
if not bar: continue
self.translated_bars.append(bar)

for bar in lyrics.split("\n"):
if not bar: continue
if len(self.bars) == len(self.translated_bars):
break
self.bars.append(bar)

assert len(self.bars) == len(self.translated_bars)

def get_random_bars(self, n: int = 1) -> list[str]:
if n == 0: return []
index_offset: int = randint(0, len(self.bars) - n)
return self.bars[index_offset: index_offset + n]

def __repr__(self) -> str:
return f"{len(self.bars)}: bars, {len(self.translated_bars)}: translated bars"


@dataclass(slots=True, init=False, repr=False)
class Song:
name: str
artist: str
lyrics: Lyrics

def __init__(self, name: str, artist: str, lyrics: str,
translated_lyrics: str) -> None:
self.name: str = name
self.artist: str = artist
self.lyrics: Lyrics = Lyrics(lyrics, translated_lyrics)
self.format_name()

def format_name(self) -> None:
result: list[str] = re.split(INVALID_PATTERN, self.name)
assert len(result) >= 1
self.name = result[0].strip()

def __repr__(self) -> str:
return f"{self.name} : {self.artist}"


class DataManager:
manager: DataManager | None = None

@staticmethod
def get() -> DataManager:
if DataManager.manager is None:
DataManager.manager = DataManager()

return DataManager.manager

@staticmethod
@st.cache_data
def get_json_data() -> list[dict[str, str]]:
return json.load(open(JSON_DATA))

def __init__(self) -> None:
self.data: list[Song] = []
self.load_json_data()

def load_json_data(self) -> None:
for song_dict in DataManager.get_json_data():
name: str | None = song_dict.get("song_name")
artist: str | None = song_dict.get("artist_name")
lyrics: str | None = song_dict.get("lyrics")
translated_lyrics: str | None = song_dict.get("translated_lyrics")
if not all([name, artist, lyrics, translated_lyrics]): continue
self.data.append(Song(name, artist, lyrics, translated_lyrics))

def get_songs(self, n=1) -> list[Song]:
songs: list[Song] = []
if len(self.data) < n:
raise Exception("ran out of songs :(")

while len(songs) < n:
song: Song = choice(self.data)
songs.append(song)
self.data.remove(song)

return songs
45 changes: 45 additions & 0 deletions src/game_database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import TypedDict

from pymongo import MongoClient
from pymongo.collection import Collection
from streamlit import secrets

MAIN: str = "Main"
SCORE: str = "Score"


class Score(TypedDict):
username: str
score: int
datetime: str


class GameDB:

@staticmethod
def get_db_uri() -> str:
user_name: str = secrets["mongo"]["username"]
user_pass: str = secrets["mongo"]["password"]

uri: str = f"mongodb+srv://{user_name}:" \
f"{user_pass}@cluster0.ec67wlo.mongodb.net/?retryWrites" \
"=true&w=majority"

return uri

def __init__(self) -> None:
self.client: MongoClient = MongoClient(GameDB.get_db_uri())
assert self.is_connected(), "not connected to database"

def is_connected(self) -> bool:
try:
self.client.admin.command('ping')
print("You successfully connected to MongoDB!")
except Exception as e:
print(e)
return False
else:
return True

def score(self) -> Collection:
return self.client[MAIN][SCORE]
37 changes: 37 additions & 0 deletions src/game_markdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import streamlit as st
from streamlit.components.v1 import html


def centered_title(title: str, color: str = "black", size: int = 45) -> None:
style: str = "<style>" \
".centered-title {" \
"text-align: center;" \
"}" \
"</style>"
st.markdown(style, unsafe_allow_html=True)
st.markdown(f"<h1 style='color: {color}; font-size: {size}px' "
f"class='centered-title'"
f">{title}</h1>", unsafe_allow_html=True)


def separator() -> None:
st.markdown("----", unsafe_allow_html=True)


def empty_space() -> None:
st.markdown("##")


def get_colored_text(text: str, color: str) -> str:
return f"<span style='color: {color}'>{text}</span>"


def scroll_text(height: int, text: str) -> None:
html_text: str = f"""
<center>
<p style="font-size:25px; font-family:verdana">
{text}
</p>
</center>
"""
html(html_text, height=height, scrolling=True)
Loading