After a small check, it seems the best solution is to add a condition per type of event, where you adjust accordingly.
Since all events have their effect 'doubled' on the last 7 days, you can use a single if for it
Lastly, you use a single if as well to check if you can update the event, regarding final price
Also I added a list comprehension to avoid looping through 'construction' events, whose value never changes
class EventPricingUpdate(object):
ORIGINAL_REDUCTION = 10
def __init__(self, events):
self.events = events
def events_to_update(self):
return [event for event in self.events if event.event_type != 'construction']
def update(self):
for event in self.events_to_update():
reduction = self.ORIGINAL_REDUCTION
if event.event_type == 'music':
reduction = reduction * -1
if event.event_type == 'sports':
reduction = reduction * 2
if event.days_from_start < 7:
reduction = reduction * 2
# if you use python 2 this if needs a slight change
if 500 >= event.price - reduction >= 50:
event.price -= reduction
event.days_from_start -= 1
return self.events
# Fill some events
events = [
Event(event_type='construction', days_from_start=10, price=100),
Event(event_type='music', days_from_start=10, price=100),
Event(event_type='sports', days_from_start=10, price=100)
]
EventPricingUpdate(events).update()
# Check update
assert events[0].price == 100
assert events[1].price == 110
assert events[2].price == 80
As you can see, is easy to plug new events, just a new condition on the loop
If you want to go further on the refactoring, you will add the reduction on the list comprehension method