code: def composition_prediction(self, composition, to_this_composition=True):
          
          preds = self.list_prediction(list(composition.keys()),
                                       to_this_composition)
          output = []
          for p in preds:
              if to_this_composition:
                  subs = {v: k for k, v in p['substitutions'].items()}
              else:
                  subs = p['substitutions']
              charge = 0
              for k, v in composition.items():
                  charge += subs[k].oxi_state * v
              if abs(charge) < 1e-8:
                  output.append(p)
          logging.info('{} charge balanced substitutions found'
                       .format(len(output)))
          return output
docs: Returns charged balanced substitutions from a starting or ending
          composition.
  
          Args:
              composition:
                  starting or ending composition
              to_this_composition:
                  If true, substitutions with this as a final composition
                  will be found. If false, substitutions with this as a
                  starting composition will be found (these are slightly
                  different)
  
          Returns:
              List of predictions in the form of dictionaries.
              If to_this_composition is true, the values of the dictionary
              will be from the list species. If false, the keys will be
              from that list.