def test_creation(unit): """Verify that a Percent Type instantiates with the properproperty values from inputs.""" value = random.randint(0, 1000) / 10 instance = PercentType(value, unit) assert isinstance(instance, PercentType) assert instance.value == value assert instance.as_(unit) == pytest.approx(value)
def from_excel(self, worksheet): """Parses out a list og Fermentable object and appends them to this instance.""" def float_or(value, fallback=None): """Return the provided value as a float or return fallback if the float conversion fails.""" try: return float(value) except TypeError: return fallback self.items = [] for idx, row in enumerate(worksheet): # Skip the header row. if idx == 0: continue self.append( Fermentable(name=str(row[0].value), ftype=str(row[1].value), group=str(row[2].value), producer=str(row[3].value), origin=str(row[4].value), fyield=PercentType(row[5].value, '%'), color=ColorType(row[6].value, 'SRM'), moisture=PercentType(row[7].value, '%'), diastaticPower=DiastaticPowerType( row[8].value, 'Lintner'), addAfterBoil=bool(row[9].value), mashed=bool(row[10].value), phi=float_or(row[11].value), bi=float_or(row[12].value), notes=str(row[13].value)))
def test_sucrose(amount, ftype, mashed, fyield, moisture, sucrose): """Verify the sucrose value for mashed and non-mashed fermentables.""" fermentable = Fermentable( amount=MassType(amount, 'lb'), ftype=ftype, fyield=PercentType(fyield, '%'), moisture=PercentType(moisture, '%'), mashed=mashed, ) assert fermentable.sucrose == pytest.approx(sucrose)
def test_copy(): """Ensure that the copy method makes a proper copy of the fermentable.""" recipe = RecipeStub() original = Fermentable( recipe=recipe, name='Test', amount=MassType(1, 'lb'), ftype='Grain', group='Smoked', producer='Crisp', origin='UK', fyield=PercentType(68, '%'), color=ColorType(45, 'SRM'), moisture=PercentType(3, '%'), diastaticPower=DiastaticPowerType(4, 'Lintner'), addAfterBoil=False, mashed=True, notes='A note', phi=5.6, bi=43.2 ) newRecipe = RecipeStub() copy = original.copy(newRecipe) assert isinstance(copy, Fermentable) assert copy.recipe == newRecipe assert copy.name == 'Test' assert isinstance(copy.amount, MassType) assert copy.amount is not original.amount # Should be a new instance of MassType. assert copy.amount.lb == 1 assert copy.ftype == 'Grain' assert copy.group == 'Smoked' assert copy.producer == 'Crisp' assert copy.origin == 'UK' assert copy.fyield is not original.fyield assert copy.fyield.percent == 68 assert copy.color is not original.color assert copy.color.SRM == 45 assert copy.moisture is not original.moisture assert copy.moisture.percent == 3 assert copy.diastaticPower is not original.diastaticPower assert copy.diastaticPower.Lintner == 4 assert copy.addAfterBoil is not None assert not copy.addAfterBoil assert copy.mashed is not None assert copy.mashed assert copy.notes == 'A note' assert copy.phi == 5.6 assert copy.bi == 43.2
def test_division_percent(): """Verify that division works using one instance of ComplexTypeSub and one instance of percent.""" instance = ComplesTypeStub(1, 'hundred') percent = PercentType(25, 'percent') assert instance is not percent assert instance.one == 100 assert percent.percent == 25 result = instance / percent # Ensure that a new instance is created with the result. assert isinstance(result, ComplesTypeStub) assert result is not instance assert result is not percent # Ensure that the original inputs were not changed. assert instance.one == 100 assert instance.unit == 'hundred' assert percent.percent == 25 assert percent.unit == '%' # Ensure that the results are correct and in the units original instance. assert result.one == 400 assert result.unit == 'hundred' # Verify that the reverse order throws a TypeError with pytest.raises(TypeError): percent / instance
def from_excel(self, worksheet): """Dump any items currently associated with this instance and reload from the provided Excel worksheet.""" self.items = [] for idx, row in enumerate(worksheet): # Skip the header row. if idx == 0: continue self.append( Culture(name=str(row[0].value), ctype=str(row[1].value), form=str(row[2].value), producer=str(row[3].value), productId=str(row[4].value), attenuationRange=PercentRangeType( minimum=PercentType(row[5].value * 100, '%'), maximum=PercentType(row[6].value * 100, '%')), notes=str(row[11].value)))
def test_to_dict(): """Ensure that the to_dict method produces a dict with the expected values.""" recipe = RecipeStub() fermentable = Fermentable( recipe=recipe, name='Test', amount=MassType(1, 'lb'), ftype='Grain', group='Smoked', producer='Crisp', origin='UK', fyield=PercentType(68, '%'), color=ColorType(45, 'SRM'), moisture=PercentType(3, '%'), diastaticPower=DiastaticPowerType(4, 'Lintner'), addAfterBoil=False, mashed=True, notes='A note\nSecond line', phi=5.6, bi=43.2 ) output = fermentable.to_dict() assert output['name'] == 'Test' assert output['type'] == 'grain' assert output['origin'] == 'UK' assert output['producer'] == 'Crisp' assert output['yield']['fine_grind']['value'] == 68 assert output['yield']['fine_grind']['unit'] == '%' assert output['color']['value'] == 45 assert output['color']['unit'] == 'SRM' assert output['amount']['value'] == 1 assert output['amount']['unit'] == 'lb' assert output['notes'] == 'A note\\nSecond line' assert output['moisture']['value'] == 3 assert output['moisture']['unit'] == '%' assert output['diastatic_power']['value'] == 4 assert output['diastatic_power']['unit'] == 'Lintner' assert output['recommend_mash'] == True assert output['grain_group'] == 'smoked' assert output['phi'] == 5.6 assert output['bi'] == 43.2
def caramel_grain(recipe, pounds): return Fermentable( recipe=recipe, name='Caramel 20', amount=MassType(pounds, 'lb'), ftype='Grain', group='Caramel', producer='Generic', origin='N/A', fyield=PercentType(68, '%'), color=ColorType(20, 'SRM'), moisture=PercentType(3, '%'), diastaticPower=DiastaticPowerType(6, 'Lintner'), addAfterBoil=False, mashed=True, notes='Not a real grain type', phi=5.2, bi=56, )
def from_excel(worksheet): styles = Styles() for idx, row in enumerate(worksheet): # Skip the header row. if idx <= 1: continue def attemptParagraph(cell): value = cell.value if value is None: return None return value.replace('\\n', '\n') style = Style( name=row[0].value, stype=row[1].value, category=row[2].value, number=row[3].value, letter=row[4].value, guide=row[5].value, og=GravityRangeType(minimum=GravityType(row[6].value, 'sg'), maximum=GravityType(row[7].value, 'sg')), fg=GravityRangeType( minimum=GravityType(row[8].value, 'sg'), maximum=GravityType(row[9].value, 'sg'), ), bitterness=BitternessRangeType( minimum=BitternessType(row[10].value, 'IBUs'), maximum=BitternessType(row[11].value, 'IBUs')), color=ColorRangeType(minimum=ColorType(row[12].value, 'SRM'), maximum=ColorType(row[13].value, 'SRM')), abv=PercentRangeType( minimum=PercentType(row[14].value * 100, '%'), maximum=PercentType(row[15].value * 100, '%')), carbonation=CarbonationRangeType( minimum=CarbonationType(row[16].value, 'vols'), maximum=CarbonationType(row[17].value, 'vols')), notes=attemptParagraph(row[18]), overall=attemptParagraph(row[19]), ingredients=attemptParagraph(row[20]), examples=attemptParagraph(row[21])) styles.append(style) return styles
def test_proper_creation(): recipe = RecipeStub() fermentable = Fermentable( recipe=recipe, name='Test Grain', amount=MassType(1, 'lb'), ftype='Grain', group='Base', producer='Generic', origin='US', fyield=PercentType(70, '%'), color=ColorType(2, 'SRM'), moisture=PercentType(6, '%'), diastaticPower=DiastaticPowerType(10, 'Lintner'), addAfterBoil=False, mashed=True, notes='Not a real grain type', phi=5.5, bi=50, ) assert fermentable.name == 'Test Grain' assert isinstance(fermentable.amount, MassType) assert fermentable.amount.lb == 1 assert fermentable.ftype == 'Grain' assert fermentable.group == 'Base' assert fermentable.group == 'Base' assert fermentable.origin == 'US' assert isinstance(fermentable.fyield, PercentType) assert fermentable.fyield.percent == 70 assert isinstance(fermentable.color, ColorType) assert fermentable.color.SRM == 2 assert isinstance(fermentable.moisture, PercentType) assert fermentable.moisture.percent == 6 assert isinstance(fermentable.diastaticPower, DiastaticPowerType) assert fermentable.diastaticPower.Lintner == 10 assert not fermentable.addAfterBoil assert fermentable.mashed assert fermentable.notes == 'Not a real grain type' assert fermentable.phi == 5.5 assert fermentable.bi == 50
def from_dict(self, data: dict): self.name = data['name'] amount = data['amount'] self.amount = Selections.one_of(amount['value'], amount['unit'], VolumeType, MassType) self.ftype = data['type'].title() if 'grain_group' in data: self.group = data['grain_group'].title() self.producer = data['producer'] self.origin = data['origin'] self.color = ColorType(json=data['color']) self.moisture = PercentType(json=data['moisture']) self.diastaticPower = DiastaticPowerType(json=data['diastatic_power']) self.fyield = PercentType(json=data['yield']['fine_grind']) self.mashed = data['recommend_mash'] self.notes = data['notes'].replace('\\n', '\n') # phi and bi are not a part of the BeerJSON standard so don't worry if they are missing. self._phi = data.get('phi') self._bi = data.get('bi')
def percentage(self): """Calculates the percentage of this water based upon the total amount of water needed.""" try: percent = self.amount.gal / self.recipe.mash.totalWater.gal except ZeroDivisionError: # We get a divide by zero error when the mash has not been calculated yet. Default to zero percent # so that it remains obvious theres an issue. percent = 0 return PercentType(percent * 100, '%')
def proportion(self) -> PercentType: """Returns a PercentType representing this fermentable's proportion within it's associated recipe.""" percent = 0 if self.recipe is not None: total = sum([ fermentable.amount.lb for fermentable in self.recipe.fermentables ]) if total != 0: percent = self.amount.lb / total * 100 return PercentType(percent, '%')
def test_to_dict_optional(): """Verify that the optional items are not set when a fermentable without explicit values is stored.""" recipe = RecipeStub() fermentable = Fermentable( recipe=recipe, name='Test', amount=MassType(1, 'lb'), ftype='Extract', producer='Crisp', origin='UK', fyield=PercentType(68, '%'), color=ColorType(45, 'SRM'), moisture=PercentType(3, '%'), diastaticPower=DiastaticPowerType(4, 'Lintner'), ) output = fermentable.to_dict() assert 'grain_group' not in output assert 'phi' not in output assert 'bi' not in output
def from_dict(self, data: dict): self.name = data['name'] amount = data['amount'] self.amount = Selections.one_of(amount['value'], amount['unit'], MassType, VolumeType) self.timing = TimingType() self.timing.from_dict(data['timing']) self.htype = data['type'].title() self.form = data['form'].title() self.alpha = PercentType(json=data['alpha_acid']) self.beta = PercentType(json=data['beta_acid']) self.hsi = PercentType(json=data['percent_lost']) self.origin = data['origin'] self.substitutes = data['substitutes'].replace('\\n', '\n') self.humulene = PercentType(json=data['oil_content']['humulene']) self.caryophyllene = PercentType(json=data['oil_content']['caryophyllene']) self.cohumulone = PercentType(json=data['oil_content']['cohumulone']) self.myrcene = PercentType(json=data['oil_content']['myrcene']) self.notes = data['notes'].replace('\\n', '\n')
def from_excel(self, worksheet): """Parses out a list of hop objects from the provided Excel worksheet and appends them to this instance.""" self.items = [] for idx, row in enumerate(worksheet): # Skip the header row. if idx == 0: continue self.append( Hop(name=str(row[0].value), htype=str(row[1].value), form=str(row[2].value), alpha=PercentType(row[3].value, '%'), beta=PercentType(row[4].value, '%'), hsi=PercentType(row[5].value, '%'), origin=str(row[6].value), substitutes=str(row[7].value), humulene=PercentType(row[8].value, '%'), caryophyllene=PercentType(row[9].value, '%'), cohumulone=PercentType(row[10].value, '%'), myrcene=PercentType(row[11].value, '%'), notes=str(row[12].value)))
def sourcePercentage(self): """Returns the PercentType value for the currently selected "source" percentage, based upon the slider.""" return PercentType(self.ui.ratio.value(), '%')
def distilledPercentage(self): """Returns the PercentType of distilled water set by the slider.""" return PercentType(100 - self.ui.ratio.value(), '%')
def test_out_of_range(value): """Verify appropriate conversions between types.""" with pytest.raises(ValueError): PercentType(value, '%')