"""
The dataset class used in this package.
Datasets consists of data used for training, represented by a list of
(feature, label) tuples.
May be exported in different formats for application on other libraries.
"""

import random


class Dataset(object):

    def __init__(self, X=[], y=[]):
        """Constructor with scikit-learn style (X, y) data"""
        self.data = list(zip(X, y))

    def __getitem__(self, key):
        """Allow list-like access: dataset[key]"""
        return self.data[key]

    def __len__(self):
        """Return the number of all data entries in this object."""
        return len(self.data)

    def len_labeled(self):
        """Return the number of labeled data entries in this object."""
        ret = 0
        for ent in self.data:
            if ent[1] != None:
                ret += 1
        return ret

    def add(self, feature, label):
        """Add a (feature, label) entry into the dataset.
        A None label indicates an unlabeled entry.
        Returns entry_id for updating labels.
        """
        self.data.append((feature, label))
        return len(self.data) - 1

    def update(self, entry_id, label):
        """Updates an entry at entry_id with the given new label"""
        self.data[entry_id] = (self.data[entry_id][0], label)

    def format_sklearn(self):
        """Returns dataset in (X, y) format for use in scikit-learn.
        Unlabeled entries are ignored.
        """
        l = list(zip(*[entry for entry in self.data if entry[1] is not None]))
        return (list(l[0]), list(l[1]))

    def get_unlabeled(self):
        """Returns list of entry_ids of unlabeled features"""
        return [entry_id for entry_id, entry in enumerate(self.data)
            if entry[1] == None]

    def labeled_uniform_sample(self, samplesize, replace=True):
        """Returns a Dataset object with labeled data only, which is
        resampled uniformly with given sample size.
        Parameter `replace` decides whether sampling with replacement or not.
        """
        ret = Dataset()
        labeled_data_id = [entry_id for entry_id, entry in enumerate(self.data)
            if entry[1] != None]
        if replace:
            for i in range(samplesize):
                ran = random.choice(labeled_data_id)
                ret.add(self.data[ran][0], self.data[ran][1])
            return ret
        else:
            ret.data = random.sample(self.data, samplesize)
            return ret

@@ -842,16 +842,167 @@
 rn ret%0A%0A
+    def get_num_of_labels(self):%0A        s = set()%0A        for d in self.data:%0A            s.add(d%5B1%5D)%0A        return (len(s)-1) #None is in this set%0A%0A
     def 
@@ -1907,16 +1907,206 @@
  None%5D%0A%0A
+    def get_labeled(self):%0A        %22%22%22Returns list of entry_ids of labeled features%22%22%22%0A        return %5Bentry_id for entry_id, entry in enumerate(self.data)%0A            if entry%5B1%5D != None%5D%0A%0A
     def 

add method get_labeled and get_num_of_label for dataset