Untitled

 avatar
user_9043509
plain_text
12 days ago
4.5 kB
2
Indexable
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