コード例 #1
0
def create_zero_filter(ingredients, zero_columns):
    """Convert column id list into specification for which columns should be
       filtered for zeros"""
    filter_map = {}
    for i in range(len(ingredients)):
        filter_map[i] = False
    column_translator = ColumnTranslator(ingredients)
    for column_id in zero_columns:
        for index in column_translator.id_to_indexes(column_id):
            filter_map[index] = True
    return filter_map
コード例 #2
0
 def __init__(self, ingredients, values):
     self.ingredients = ingredients
     self._settings = {}
     self.set_precision(2)
     self._restrictions = []
     self._column_translator = ColumnTranslator(self.ingredients)
     self._elements = [RatioElement(values[i], ingredients[i],
                                 self._settings) for i in range(len(values))]
コード例 #3
0
class Ratio(object):
    """Provides formatting for ingredient ratios and related statistics"""
    
    def __init__(self, ingredients, values):
        self.ingredients = ingredients
        self._settings = {}
        self.set_precision(2)
        self._restrictions = []
        self._column_translator = ColumnTranslator(self.ingredients)
        self._elements = [RatioElement(values[i], ingredients[i],
                                    self._settings) for i in range(len(values))]

    def _column_id_to_indexes(self, column_identifier):
        """Normalize column identifier to a column index"""
        return self._column_translator.id_to_indexes(column_identifier)

    def _values(self, scale=1):
        """Return raw ratio values"""
        for element in self._elements:
            yield element.value(scale)
            
    def _restrict_total_weight(self, weight):
        """Yield ratio proportions with specific total weight. Returns scale
           applied."""
        total_grams = sum(self._values())
        return weight / float(total_grams)

    def _restrict_by_ingredient(self, scale):
        """Restrict a recipe based on individual ingredient/weight-limit
           specifications"""
        for column_indexes, weight_limit in self._restrictions:
            scaled_weight = sum(self._elements[index].value(scale) for \
                                index in column_indexes)
            unscaled_weight = sum(self._elements[index].value() for \
                                index in column_indexes)
            if scaled_weight > weight_limit:
                new_scale = weight_limit / unscaled_weight
                if new_scale < scale:
                    scale = new_scale
        return scale

    def set_restrictions(self, restrictions):
        """Individual ingredient weight restrictions"""
        _restrictions = []
        for column_id, weight in restrictions:
            indexes = self._column_id_to_indexes(column_id)
            _restrictions.append((indexes, weight))
        self._restrictions = _restrictions

    def len(self):
        """Return number of ratio elements"""
        return len(self._elements)
            
    def set_precision(self, precision):
        """Set precision (i.e. number of digits shown after decimal point)
           for floating point percentages."""
        self._settings["float_format"] = "%1." + "%df" % precision
    
    def list_ingredients(self):
        """List the ingredients in the same order as they will appear in the
           ratio."""
        return " (" + ":".join(str(c) for c in self.ingredients) + ")"
    
    def __str__(self):
        return (":".join(str(element) \
                    for element in self._elements)) + self.list_ingredients()
                    
    def describe_ingredient(self, column_id):
        """Describe individual ingredients"""
        return "\n".join(self._elements[index].describe(scale=1) \
                         for index in self._column_id_to_indexes(column_id))
    
    def recipe(self, weight):
        """Format the ingredient proportions as if for a recipe ingredient
           list. Also return total weight."""
        scale = self._restrict_total_weight(weight)
        scale = self._restrict_by_ingredient(scale)
        total_weight = sum(self._values(scale))
        return total_weight, "\n".join(element.describe(scale) \
                         for element in self._elements)
    
    def as_percentages(self):
        """Return ratio values as percentages"""
        scale =  self._restrict_total_weight(100)
        return list(self._values(scale))