class_docstr: Encode labels of a discrete set.
  
  Used for encoding, e.g., speaker identities in speaker recognition.
  Given a collection of hashables (e.g a strings) it encodes
  every unique item to an integer value: ["spk0", "spk1"] --> [0, 1]
  Internally the correspondence between each label to its index is handled by
  two dictionaries: lab2ind and ind2lab.
  
  The label integer encoding can be generated automatically from a SpeechBrain
  DynamicItemDataset by specifying the desired entry (e.g., spkid) in the annotation
  and calling update_from_didataset method:
  
  >>> from speechbrain.dataio.encoder import CategoricalEncoder
  >>> from speechbrain.dataio.dataset import DynamicItemDataset
  >>> dataset = {"ex_{}".format(x) : {"spkid" : "spk{}".format(x)} for x in range(20)}
  >>> dataset = DynamicItemDataset(dataset)
  >>> encoder = CategoricalEncoder()
  >>> encoder.update_from_didataset(dataset, "spkid")
  >>> assert len(encoder) == len(dataset) # different speaker for each utterance
  
  However can also be updated from an iterable:
  
  >>> from speechbrain.dataio.encoder import CategoricalEncoder
  >>> from speechbrain.dataio.dataset import DynamicItemDataset
  >>> dataset = ["spk{}".format(x) for x in range(20)]
  >>> encoder = CategoricalEncoder()
  >>> encoder.update_from_iterable(dataset)
  >>> assert len(encoder) == len(dataset)
  
  Note
  ----
  In both methods it can be specified it the single element in the iterable
  or in the dataset should be treated as a sequence or not (default False).
  If it is a sequence each element in the sequence will be encoded.
  
  
  >>> from speechbrain.dataio.encoder import CategoricalEncoder
  >>> from speechbrain.dataio.dataset import DynamicItemDataset
  >>> dataset = [[x+1, x+2] for x in range(20)]
  >>> encoder = CategoricalEncoder()
  >>> encoder.ignore_len()
  >>> encoder.update_from_iterable(dataset, sequence_input=True)
  >>> assert len(encoder) == 21 # there are only 21 unique elements 1-21
  
  This class offers 4 different methods to explicitly add a label in the internal
  dicts: add_label, ensure_label, insert_label, enforce_label.
  add_label and insert_label will raise an error if it is already present in the
  internal dicts. insert_label, enforce_label allow also to specify the integer value
  to which the desired label is encoded.
  
  Encoding can be performed using 4 different methods:
  encode_label, encode_sequence, encode_label_torch and encode_sequence_torch.
  encode_label operate on single labels and simply returns the corresponding
  integer encoding:
  
  >>> from speechbrain.dataio.encoder import CategoricalEncoder
  >>> from speechbrain.dataio.dataset import DynamicItemDataset
  >>> dataset = ["spk{}".format(x) for x in range(20)]
  >>> encoder.update_from_iterable(dataset)
  >>>
  22
  >>>
  encode_sequence on sequences of labels:
  >>> encoder.encode_sequence(["spk1", "spk19"])
  [22, 40]
  >>>
  encode_label_torch and encode_sequence_torch return torch tensors
  >>> encoder.encode_sequence_torch(["spk1", "spk19"])
  tensor([22, 40])
  >>>
  Decoding can be performed using decode_torch and decode_ndim methods.
  >>> encoded = encoder.encode_sequence_torch(["spk1", "spk19"])
  >>> encoder.decode_torch(encoded)
  ['spk1', 'spk19']
  >>>
  decode_ndim is used for multidimensional list or pytorch tensors
  >>> encoded = encoded.unsqueeze(0).repeat(3, 1)
  >>> encoder.decode_torch(encoded)
  [['spk1', 'spk19'], ['spk1', 'spk19'], ['spk1', 'spk19']]
  >>>
  
  In some applications, it can happen that during testing a label which has not
  been encountered during training is encountered. To handle this out-of-vocabulary
  problem add_unk can be used. Every out-of-vocab label is mapped to this special
  <unk> label and its corresponding integer encoding.
  
  >>> import torch
  >>> try:
  ...     encoder.encode_label("spk42")
  ... except KeyError:
  ...        print("spk42 is not in the encoder this raises an error!")
  spk42 is not in the encoder this raises an error!
  >>> encoder.add_unk()
  41
  >>> encoder.encode_label("spk42")
  41
  >>>
  returns the <unk> encoding
  
  This class offers also methods to save and load the internal mappings between
  labels and tokens using: save and load methods as well as load_or_create.
class_docstr_tok: ["Encode","labels","of","a","discrete","set",".","Used","for","encoding",",","e.g.",",","speaker","identities","in","speaker","recognition",".","Given","a","collection","of","hashables","(","e.g","a","strings",")","it","encodes","every","unique","item","to","an","integer","value",":","[","``","spk0","''",",","``","spk1","''","]","--",">","[","0",",","1","]","Internally","the","correspondence","between","each","label","to","its","index","is","handled","by","two","dictionaries",":","lab2ind","and","ind2lab",".","The","label","integer","encoding","can","be","generated","automatically","from","a","SpeechBrain","DynamicItemDataset","by","specifying","the","desired","entry","(","e.g.",",","spkid",")","in","the","annotation","and","calling","update_from_didataset","method",":",">",">",">","from","speechbrain.dataio.encoder","import","CategoricalEncoder",">",">",">","from","speechbrain.dataio.dataset","import","DynamicItemDataset",">",">",">","dataset","=","{","``","ex_","{","}","''",".format","(","x",")",":","{","``","spkid","''",":","``","spk","{","}","''",".format","(","x",")","}","for","x","in","range","(","20",")","}",">",">",">","dataset","=","DynamicItemDataset","(","dataset",")",">",">",">","encoder","=","CategoricalEncoder","(",")",">",">",">","encoder.update_from_didataset","(","dataset",",","``","spkid","''",")",">",">",">","assert","len","(","encoder",")","==","len","(","dataset",")","#","different","speaker","for","each","utterance","However","can","also","be","updated","from","an","iterable",":",">",">",">","from","speechbrain.dataio.encoder","import","CategoricalEncoder",">",">",">","from","speechbrain.dataio.dataset","import","DynamicItemDataset",">",">",">","dataset","=","[","``","spk","{","}","''",".format","(","x",")","for","x","in","range","(","20",")","]",">",">",">","encoder","=","CategoricalEncoder","(",")",">",">",">","encoder.update_from_iterable","(","dataset",")",">",">",">","assert","len","(","encoder",")","==","len","(","dataset",")","Note","--","--","In","both","methods","it","can","be","specified","it","the","single","element","in","the","iterable","or","in","the","dataset","should","be","treated","as","a","sequence","or","not","(","default","False",")",".","If","it","is","a","sequence","each","element","in","the","sequence","will","be","encoded",".",">",">",">","from","speechbrain.dataio.encoder","import","CategoricalEncoder",">",">",">","from","speechbrain.dataio.dataset","import","DynamicItemDataset",">",">",">","dataset","=","[","[","x+1",",","x+2","]","for","x","in","range","(","20",")","]",">",">",">","encoder","=","CategoricalEncoder","(",")",">",">",">","encoder.ignore_len","(",")",">",">",">","encoder.update_from_iterable","(","dataset",",","sequence_input=True",")",">",">",">","assert","len","(","encoder",")","==","21","#","there","are","only","21","unique","elements","1-21","This","class","offers","4","different","methods","to","explicitly","add","a","label","in","the","internal","dicts",":","add_label",",","ensure_label",",","insert_label",",","enforce_label",".","add_label","and","insert_label","will","raise","an","error","if","it","is","already","present","in","the","internal","dicts",".","insert_label",",","enforce_label","allow","also","to","specify","the","integer","value","to","which","the","desired","label","is","encoded",".","Encoding","can","be","performed","using","4","different","methods",":","encode_label",",","encode_sequence",",","encode_label_torch","and","encode_sequence_torch",".","encode_label","operate","on","single","labels","and","simply","returns","the","corresponding","integer","encoding",":",">",">",">","from","speechbrain.dataio.encoder","import","CategoricalEncoder",">",">",">","from","speechbrain.dataio.dataset","import","DynamicItemDataset",">",">",">","dataset","=","[","``","spk","{","}","''",".format","(","x",")","for","x","in","range","(","20",")","]",">",">",">","encoder.update_from_iterable","(","dataset",")",">",">",">","22",">",">",">","encode_sequence","on","sequences","of","labels",":",">",">",">","encoder.encode_sequence","(","[","``","spk1","''",",","``","spk19","''","]",")","[","22",",","40","]",">",">",">","encode_label_torch","and","encode_sequence_torch","return","torch","tensors",">",">",">","encoder.encode_sequence_torch","(","[","``","spk1","''",",","``","spk19","''","]",")","tensor","(","[","22",",","40","]",")",">",">",">","Decoding","can","be","performed","using","decode_torch","and","decode_ndim","methods",".",">",">",">","encoded","=","encoder.encode_sequence_torch","(","[","``","spk1","''",",","``","spk19","''","]",")",">",">",">","encoder.decode_torch","(","encoded",")","[","'spk1","'",",","'spk19","'","]",">",">",">","decode_ndim","is","used","for","multidimensional","list","or","pytorch","tensors",">",">",">","encoded","=","encoded.unsqueeze","(","0",")",".repeat","(","3",",","1",")",">",">",">","encoder.decode_torch","(","encoded",")","[","[","'spk1","'",",","'spk19","'","]",",","[","'spk1","'",",","'spk19","'","]",",","[","'spk1","'",",","'spk19","'","]","]",">",">",">","In","some","applications",",","it","can","happen","that","during","testing","a","label","which","has","not","been","encountered","during","training","is","encountered",".","To","handle","this","out-of-vocabulary","problem","add_unk","can","be","used",".","Every","out-of-vocab","label","is","mapped","to","this","special","<","unk",">","label","and","its","corresponding","integer","encoding",".",">",">",">","import","torch",">",">",">","try",":","...","encoder.encode_label","(","``","spk42","''",")","...","except","KeyError",":","...","print","(","``","spk42","is","not","in","the","encoder","this","raises","an","error","!","''",")","spk42","is","not","in","the","encoder","this","raises","an","error","!",">",">",">","encoder.add_unk","(",")","41",">",">",">","encoder.encode_label","(","``","spk42","''",")","41",">",">",">","returns","the","<","unk",">","encoding","This","class","offers","also","methods","to","save","and","load","the","internal","mappings","between","labels","and","tokens","using",":","save","and","load","methods","as","well","as","load_or_create","."]
docstr: Make sure label is present and encoded to a particular index.
  
  If the label is present but encoded to some other index, it is
  moved to the given index.
  
  If there is already another label at the
  given index, that label is moved to the next free position.
docstr_tok: ["Make","sure","label","is","present","and","encoded","to","a","particular","index",".","If","the","label","is","present","but","encoded","to","some","other","index",",","it","is","moved","to","the","given","index",".","If","there","is","already","another","label","at","the","given","index",",","that","label","is","moved","to","the","next","free","position","."]
code: def enforce_label(self, label, index):
      """Make sure label is present and encoded to a particular index.
  
      If the label is present but encoded to some other index, it is
      moved to the given index.
  
      If there is already another label at the
      given index, that label is moved to the next free position.
      """
      index = int(index)
      if label in self.lab2ind:
          if index == self.lab2ind[label]:
              return
          else:
              # Delete old index mapping. Everything else gets overwritten.
              del self.ind2lab[self.lab2ind[label]]
      # Move other label out of the way:
      if index in self.ind2lab:
          saved_label = self.ind2lab[index]
          moving_other = True
      else:
          moving_other = False
      # Ready to push the new index.
      self.lab2ind[label] = index
      self.ind2lab[index] = label
      # And finally put the moved index in new spot.
      if moving_other:
          logger.info(
              f"Moving label {repr(saved_label)} from index "
              f"{index}, because {repr(label)} was put at its place."
          )
          new_index = self._next_index()
          self.lab2ind[saved_label] = new_index
          self.ind2lab[new_index] = saved_label
  
imports: import ast
  import torch
  import collections
  import itertools
  import logging
  import warnings
  import speechbrain
  from speechbrain.utils.checkpoints import mark_as_saver, mark_as_loader, register_checkpoint_hooks
label_desc: Use image node_id 12 for calling the CategoricalEncoder obj's underlying member method code with example usage: obj.enforce_label(label, index) without return types