from functools import reduce

"""
Problem 1:
Create a class called Vehicle. A Vehicle should have a weight and horsepower attribute.
"""
class Vehicle:
    def __init__(self, weight, horsepower):
        self.weight = weight
        self.horsepower = horsepower
    
    def drive(self):
        print("The vehicle is now driving.")
    
    def stop(self):
        print("The vehicle is now stopping.")

class Car(Vehicle):
    def __init__(self, weight, horsepower):
        super().__init__(weight, horsepower)
        self.wheels = 4

class Motorcycle(Vehicle):
    def __init__(self, weight, horsepower):
        super().__init__(weight, horsepower)
        self.wheels = 2
    
    def wheelie(self):
        print("The motorcycle is doing a wheelie!")

class Truck(Vehicle):
    def __init__(self, weight, horsepower):
        super().__init__(weight, horsepower)
        self.wheels = 6
    
    def dump(self):
        print("The truck is dumping its load!")

"""
Problem 2:  
Create a class called NumericList that behaves just like a List except it has an additional method called `product` that will calculate the product of the items in the list.
"""
class NumericList(list):
    def product(self):
        return reduce(lambda x, y: x * y, self, 1)
    
"""
Problem 3:
This module contains a customer class that allows us to model customers in
our code
Add the method 'get_first_purchase' which will return the value of the first purchase the customer 
has made.  Also, add the method 'get_num_purchases' which will return the number of 
purchases the customer has made. Also, add 'get_sum_of_purchases' which will return the sum 
of all the purchases the customer has made.
"""    
from datetime import datetime

class Customer:
    '''
    A class to model customers

    Parameters
    ----------
    customer_number : int, str
        the numerical customer id

    customer_info_filepath : str
        the filepath to the customer info file

    purchases_filepath : str
        the filepath to the purchases file

    '''
    def __init__(self, customer_number, customer_info_filepath, purchases_filepath):
        self.customer_number = str(customer_number)
        self.customer_info_filepath = customer_info_filepath
        self.purchases_filepath = purchases_filepath
        self.purchases = {}

    def _load_customer_info(self):
        '''Load the data from the customer info file for this customer'''
        with open(self.customer_info_filepath, 'r') as read_file:
            for line in read_file:
                line_splits = line.strip().split(',')
                if line_splits[0] == self.customer_number:
                    self.name = line_splits[1]
                    self.age = line_splits[2]
                    self.state = line_splits[3]
                    break

    def _load_purchases(self):
        '''Load the purchases data from the purchases file, for this customer'''
        with open(self.purchases_filepath, 'r') as read_file:
            for line in read_file:
                line_splits = line.strip().split(',')
                if line_splits[0] == self.customer_number:
                    purchase_date = datetime.strptime(line_splits[1], "%Y-%m-%d %H:%M:%S")
                    purchase_value = float(line_splits[2])  # Ensure purchases are stored as numerical values
                    self.purchases[purchase_date] = purchase_value

    def load_data(self):
        '''Load all the customers data'''
        self._load_customer_info()
        self._load_purchases()

    def get_last_purchase(self):
        '''Return the most recent purchase made by the customer'''
        if not self.purchases:
            return None
        return self.purchases[max(self.purchases.keys())]

    def get_first_purchase(self):
        '''Return the first purchase made by the customer'''
        if not self.purchases:
            return None
        return self.purchases[min(self.purchases.keys())]

    def get_num_purchases(self):
        '''Return the number of purchases the customer has made'''
        return len(self.purchases)

    def get_sum_of_purchases(self):
        '''Return the sum of all purchases made by the customer'''
        return sum(self.purchases.values())

