feat: python kata

This commit is contained in:
Arend Hummeling 2024-04-26 13:32:33 +02:00
parent c7e0b4a8d9
commit 87fab522b2
No known key found for this signature in database
GPG Key ID: 4389B803B9BF2A81
2 changed files with 129 additions and 40 deletions

View File

@ -1,41 +1,5 @@
# -*- coding: utf-8 -*-
class GildedRose(object):
def __init__(self, items):
self.items = items
def update_quality(self):
for item in self.items:
if item.name != "Aged Brie" and item.name != "Backstage passes to a TAFKAL80ETC concert":
if item.quality > 0:
if item.name != "Sulfuras, Hand of Ragnaros":
item.quality = item.quality - 1
else:
if item.quality < 50:
item.quality = item.quality + 1
if item.name == "Backstage passes to a TAFKAL80ETC concert":
if item.sell_in < 11:
if item.quality < 50:
item.quality = item.quality + 1
if item.sell_in < 6:
if item.quality < 50:
item.quality = item.quality + 1
if item.name != "Sulfuras, Hand of Ragnaros":
item.sell_in = item.sell_in - 1
if item.sell_in < 0:
if item.name != "Aged Brie":
if item.name != "Backstage passes to a TAFKAL80ETC concert":
if item.quality > 0:
if item.name != "Sulfuras, Hand of Ragnaros":
item.quality = item.quality - 1
else:
item.quality = item.quality - item.quality
else:
if item.quality < 50:
item.quality = item.quality + 1
class Item:
def __init__(self, name, sell_in, quality):
self.name = name
@ -44,3 +8,88 @@ class Item:
def __repr__(self):
return "%s, %s, %s" % (self.name, self.sell_in, self.quality)
class BaseRule:
def __init__(self, degrade_rate: int = -1) -> None:
self.degrade_rate = degrade_rate
def _calculate_quality_diff(self, item: Item) -> int:
sell_date_multiplier = 1 + int(item.sell_in < 0)
return self.degrade_rate * sell_date_multiplier
def update_quality(self, item: Item) -> None:
calculated_new_quality = item.quality + self._calculate_quality_diff(item)
# The quality of an item is never more than 50 and is never less than 0
item.quality = min(50, max(0, calculated_new_quality))
class IncreasingQualityRule(BaseRule):
def __init__(self) -> None:
super().__init__(1)
class SulfurasRule(BaseRule):
def update_quality(self, item: Item) -> None:
# "Sulfuras", being a legendary item, never has to be sold or decreases in Quality
item.quality = 80
class BackstageRule(IncreasingQualityRule):
def _calculate_quality_diff(self, item: Item) -> int:
# If there are more than 10 days until the concert, same rules as parent class apply
if item.sell_in > 10:
return super()._calculate_quality_diff(item)
# If there are 10 or fewer days until the concert, but more than 5, degrade_rate = 2
if item.sell_in > 5:
return 2
# If there are 5 or fewer days until the concert, degrade_rate = 2
return 3
def update_quality(self, item: Item) -> None:
# Tickets are useless when the concert is in the past
if item.sell_in < 0:
item.quality = 0
return
super().update_quality(item)
class ConjuredRule(BaseRule):
def __init__(self):
super().__init__(-2)
class RuleProvider:
def __init__(self):
self.base_rule = BaseRule()
self.increasing_quality_rule = IncreasingQualityRule()
self.sulfuras_rule = SulfurasRule()
self.backstage_rule = BackstageRule()
self.conjured_rule = ConjuredRule()
def get_rule_for_item_name(self, name: str) -> BaseRule:
if name.lower().startswith('sulfuras'):
return self.sulfuras_rule
if name.lower().startswith('aged'):
return self.increasing_quality_rule
if name.lower().startswith('backstage'):
return self.backstage_rule
if name.lower().startswith('conjured'):
return self.conjured_rule
return self.base_rule
class GildedRose(object):
def __init__(self, items: list[Item]) -> None:
self.items = items
self.rule_provider = RuleProvider()
def update_quality_over_range(self, update_range: int) -> None:
for _ in range(update_range): self.update_quality()
def update_quality(self) -> None:
self.advance_day()
for item in self.items: self.rule_provider.get_rule_for_item_name(item.name).update_quality(item)
def advance_day(self) -> None:
for item in self.items: item.sell_in -= 1

View File

@ -5,12 +5,52 @@ from gilded_rose import Item, GildedRose
class GildedRoseTest(unittest.TestCase):
def test_foo(self):
items = [Item("foo", 0, 0)]
def test_base_rule(self):
items = [Item('+5 Dexterity Vest', 16, 50)]
gilded_rose = GildedRose(items)
gilded_rose.update_quality()
self.assertEqual("fixme", items[0].name)
self.assertEqual(15, items[0].sell_in)
self.assertEqual(49, items[0].quality)
gilded_rose.update_quality_over_range(15)
self.assertEqual(0, items[0].sell_in)
self.assertEqual(34, items[0].quality)
gilded_rose.update_quality()
self.assertEqual(15, items[0].sell_in)
self.assertEqual(49, items[0].quality)
def test_backstage_rule(self):
items = [Item('Backstage passes to a TAFKAL80ETC concert', 16, 0)]
gilded_rose = GildedRose(items)
gilded_rose.update_quality()
self.assertEqual(15, items[0].sell_in)
self.assertEqual(1, items[0].quality)
gilded_rose.update_quality_over_range(4)
self.assertEqual(11, items[0].sell_in)
self.assertEqual(5, items[0].quality)
gilded_rose.update_quality()
self.assertEqual(10, items[0].sell_in)
self.assertEqual(7, items[0].quality)
gilded_rose.update_quality_over_range(4)
self.assertEqual(6, items[0].sell_in)
self.assertEqual(15, items[0].quality)
gilded_rose.update_quality()
self.assertEqual(5, items[0].sell_in)
self.assertEqual(18, items[0].quality)
gilded_rose.update_quality_over_range(5)
self.assertEqual(0, items[0].sell_in)
self.assertEqual(33, items[0].quality)
gilded_rose.update_quality()
self.assertEqual(-1, items[0].sell_in)
self.assertEqual(0, items[0].quality)
if __name__ == '__main__':
unittest.main()