<commit_before>import sqlite3

DEFAULT_VALUE = [0.0, 0.0, 0, 0.0, 0, 0, 0.0, []]


class MSFeatures:
    def __init__(self, values=DEFAULT_VALUE):
        """
        You may provide initial values for the features as a list in this order:

        1. Hotness
        2. Duration
        3. Key
        4. Loudness
        5. Year
        6. Time Signature
        7. Tempo
        8. Tags

        :param values: The values provided
        """
        self.hotness = values[0]
        self.duration = values[1]
        self.key = values[2]
        self.loudness = values[3]
        self.year = values[4]
        self.time_signature = values[5]
        self.tempo = values[6]
        self.tags = values[7]

    def vector(self):
        """

        :return:
        """
        return [self.hotness,
                self.duration,
                self.key,
                self.loudness,
                self.year,
                self.time_signature,
                self.tempo]


class MillionSongFeatureDatabase:
    def __init__(self, db):
        """

        :param db:
        """
        conn = sqlite3.connect(db)
        self.db = conn.cursor()
        self._fstart = 2  # Feature start index

    def close(self):
        self.db.close()

    def get_features_by_msd(self, track_id):
        """
        Fetches features for a song by MSD ID.
        :param track_id: Million Songs Data set ID
        :return:
        """
        track_id = (track_id,)
        for row in self.db.execute('SELECT * FROM songs WHERE track_id=?', track_id):
            return MSFeatures(row[self._fstart:])

    def get_features_by_echo(self, echo_id):
        """
        Fetches features for a song by Echo Nest ID.
        :param echo_id: Echo Nest ID
        :return:
        """
        echo_id = (echo_id,)
        for row in self.db.execute('SELECT * FROM songs WHERE song_id=?', echo_id):
            return row[self._fstart:]

    def get_features_by_msd_list(self, track_ids):
        """

        :param track_ids:
        :return:
        """
        ids = set(track_ids)
        track_id_idx = 0
        for row in self.db.execute('SELECT * FROM songs WHERE ' + \
                                   'hotttness<>? AND ' + \
                                   # 'danceability<>? AND ' + \
                                   'duration<>? AND ' + \
                                   'key<>? AND ' + \
                                   # 'energy<>? AND ' + \
                                   'loudness<>? AND ' + \
                                   'year<>? AND ' + \
                                   'time_signature<>? AND ' + \
                                   'tempo<>?',
                                   (0.0, 0.0, 0,0.0,  0, 0, 0.0)):
            if row[track_id_idx] in ids:
                yield MSFeatures(row[self._fstart:])
        
    def get_songs_with_all_features(self):
        """

        :return: Returns a list of MSD IDs for all songs which have all features populated.
        """
        track_id_idx = 0
        for row in self.db.execute('SELECT * FROM songs WHERE ' + \
                                   'hotttness<>? AND ' + \
                                   # 'danceability<>? AND ' + \
                                   'duration<>? AND ' + \
                                   'key<>? AND ' + \
                                   # 'energy<>? AND ' + \
                                   'loudness<>? AND ' + \
                                   'year<>? AND ' + \
                                   'time_signature<>? AND ' + \
                                   'tempo<>?',
                                   (0.0, 0.0, 0, 0.0, 0, 0, 0.0)):
            yield row[track_id_idx]


class MillionSongLyricDatabase:
    def __init__(self, db, mappings):
        """
        :param db: Path to musiXmatch lyric database.
        :param mappings: Link to mappings file for lyric database. This should
                    be a single-line file with comma-separated word values
                    corresponding the 5,000 reported BOW words for the
                    musixmatch data set.
        """
        conn = sqlite3.connect(db)
        self.db = conn.cursor()

        # The lyric database is built as a bag-of-words (BOW) for each song
        # over 5,000 carefully selected, discriminative, and common words<commit_msg>Add relative path checking for .db files<commit_after>import sqlite3
import os.path

DEFAULT_VALUE = [0.0, 0.0, 0, 0.0, 0, 0, 0.0, []]
class MSFeatures:
    def __init__(self, values=DEFAULT_VALUE):
        """
        You may provide initial values for the features as a list in this order:

        1. Hotness
        2. Duration
        3. Key
        4. Loudness
        5. Year
        6. Time Signature
        7. Tempo
        8. Tags

        :param values: The values provided
        """
        self.hotness = values[0]
        self.duration = values[1]
        self.key = values[2]
        self.loudness = values[3]
        self.year = values[4]
        self.time_signature = values[5]
        self.tempo = values[6]
        self.tags = values[7]

    def vector(self):
        """

        :return:
        """
        return [self.hotness,
                self.duration,
                self.key,
                self.loudness,
                self.year,
                self.time_signature,
                self.tempo]


class MillionSongFeatureDatabase:
    def __init__(self, db):
        """

        :param db:
        """
	BASE_DIR = os.path.dirname(os.path.abspath(__file__))
	db_path = os.path.join(BASE_DIR, db)
	conn = sqlite3.connect(db_path)
        self.db = conn.cursor()
        self._fstart = 2  # Feature start index

    def close(self):
        self.db.close()

    def get_features_by_msd(self, track_id):
        """
        Fetches features for a song by MSD ID.
        :param track_id: Million Songs Data set ID
        :return:
        """
        track_id = (track_id,)
        for row in self.db.execute('SELECT * FROM songs WHERE track_id=?', track_id):
            return MSFeatures(row[self._fstart:])

    def get_features_by_echo(self, echo_id):
        """
        Fetches features for a song by Echo Nest ID.
        :param echo_id: Echo Nest ID
        :return:
        """
        echo_id = (echo_id,)
        for row in self.db.execute('SELECT * FROM songs WHERE song_id=?', echo_id):
            return row[self._fstart:]

    def get_features_by_msd_list(self, track_ids):
        """

        :param track_ids:
        :return:
        """
        ids = set(track_ids)
        track_id_idx = 0
        for row in self.db.execute('SELECT * FROM songs WHERE ' + \
                                   'hotttness<>? AND ' + \
                                   # 'danceability<>? AND ' + \
                                   'duration<>? AND ' + \
                                   'key<>? AND ' + \
                                   # 'energy<>? AND ' + \
                                   'loudness<>? AND ' + \
                                   'year<>? AND ' + \
                                   'time_signature<>? AND ' + \
                                   'tempo<>?',
                                   (0.0, 0.0, 0,0.0,  0, 0, 0.0)):
            if row[track_id_idx] in ids:
                yield MSFeatures(row[self._fstart:])
        
    def get_songs_with_all_features(self):
        """

        :return: Returns a list of MSD IDs for all songs which have all features populated.
        """
        track_id_idx = 0
        for row in self.db.execute('SELECT * FROM songs WHERE ' + \
                                   'hotttness<>? AND ' + \
                                   # 'danceability<>? AND ' + \
                                   'duration<>? AND ' + \
                                   'key<>? AND ' + \
                                   # 'energy<>? AND ' + \
                                   'loudness<>? AND ' + \
                                   'year<>? AND ' + \
                                   'time_signature<>? AND ' + \
                                   'tempo<>?',
                                   (0.0, 0.0, 0, 0.0, 0, 0, 0.0)):
            yield row[track_id_idx]


class MillionSongLyricDatabase:
    def __init__(self, db, mappings):
        """
        :param db: Path to musiXmatch lyric database.
        :param mappings: Link to mappings file for lyric database. This should
                    be a single-line file with comma-separated word values
                    corresponding the 5,000 reported BOW words for the
                    musixmatch data set.
        """
       	BASE_DIR = os.path.dirname(os.path.abspath(__file__))
	db_path = os.path.join(BASE_DIR, db)
        conn = sqlite3.connect(db_path)
        self.db = conn.cursor()

        # The lyric database is built as a bag-of-words (BOW) for each song
        # over 5,000 carefully selected, discriminative, and common words
{'fraction_non_alphanumeric': 0.10507569011576136, 'fraction_numerical': 0.01402493321460374, 'mean_word_length': 1.2092451438406688, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2516481', 'n_tokens_mistral': 2672, 'n_tokens_neox': 2476, 'n_words': 667}