Untitled
import csv import sys from datetime import datetime from collections import defaultdict class Zones: def __init__(self, zone_map_file): self.zone_map = self.load_zone(zone_map_file) def load_zone(self, zone_map_file): zone_map = {} with open(zone_map_file, 'r') as csvfile: read_file = csv.DictReader(csvfile) for row in read_file: zone_map[row['station']] = int(row['zone']) return zone_map def get_zone(self, station): zone_num = self.zone_map.get(station) return zone_num class JourneyManager: BASE_FEE = 2.00 ZONE_FEES = [0.80, 0.50, 0.30, 0.10] DAILY_CAP = 15.00 MONTHLY_CAP = 100.00 def __init__(self, zone_map, journey_data): self.zone_map = zone_map self.journeys = journey_data self.active_journeys = {} self.user_charge = defaultdict(float) def process_all_journeys(self): for journey in self.journeys: self.process_journey( journey['user_id'], journey['station'], journey['direction'], journey['time'] ) def process_journey(self, user_id, station, direction, time): if direction == "IN": self.process_entry(user_id, station, time) elif direction == "OUT": self.process_exit(user_id, station, time) def process_entry(self, user_id, station, time): if user_id in self.active_journeys: self.user_charge[user_id] += 5.00 self.active_journeys[user_id] = {'station': station, 'time': time} def process_exit(self, user_id, station, time): if user_id not in self.active_journeys: self.user_charge[user_id] += 5.00 else: entry_station = self.active_journeys[user_id]['station'] entry_zone = self.zone_map.get_zone(entry_station) # From the Zone class exit_zone = self.zone_map.get_zone(station) if entry_zone and exit_zone: cost = self.calculate_charge(entry_zone, exit_zone) self.user_charge[user_id] += cost else: self.user_charge[user_id] += 5.00 del self.active_journeys[user_id] def calculate_charge(self, entry_zone, exit_zone): entry_cost = self.ZONE_FEES[entry_zone - 1] exit_cost = self.ZONE_FEES[exit_zone - 1] return entry_cost + exit_cost + self.BASE_FEE def final_charge(self): for user_id in self.active_journeys: self.user_charge[user_id] += 5.00 for user_id in self.user_charge: self.user_charge[user_id] = min(self.user_charge[user_id], self.MONTHLY_CAP) finalized_charge = {} for user_id, charge in self.user_charge.items(): finalized_charge[user_id] = round(charge, 2) return finalized_charge class LoadJourney: @staticmethod def load_journey_data(journey_data): journeys = [] with open(journey_data, 'r') as csvfile: read_file = csv.DictReader(csvfile) # Corrected usage of csv.DictReader for row in read_file: journeys.append({ 'user_id': row['user_id'], 'station': row['station'], 'direction': row['direction'], 'time': datetime.strptime(row['time'], '%Y-%m-%dT%H:%M:%S') }) return journeys class OutputFile: @staticmethod def save_output(output, user_charge): with open(output, 'w', newline='') as file: write_to_file = csv.writer(file) write_to_file.writerow(['user_id', 'billing_amount']) for user_id in sorted(user_charge): write_to_file.writerow([user_id, f'{user_charge[user_id]: .2f}']) def main(zone_map, journey_data, output): zone_map = Zones(zone_map) journeys = LoadJourney.load_journey_data(journey_data) processor = JourneyManager(zone_map, journeys) processor.process_all_journeys() user_charge = processor.final_charge() OutputFile.save_output(output, user_charge) if __name__ == "__main__": if len(sys.argv) != 4: print("Usage: python billing_system.py <zone_map.csv> <journey_data.csv> <output.csv>") sys.exit(1) zone_map = sys.argv[1] journey_data = sys.argv[2] output = sys.argv[3] main(zone_map, journey_data, output)
Leave a Comment