Answered step by step
Verified Expert Solution
Link Copied!
Question
1 Approved Answer

USE PYTHON 3.9 . ONLY NEED TO IMPLEMENT 1 METHOD(ignore the first one): IMPORTANT !!! MAKE COMMENTS AND PROVIDE A DETAILED DOCUMENTATION OF THE METHOD

USE PYTHON 3.9 . ONLY NEED TO IMPLEMENT 1 METHOD(ignore the first one):

IMPORTANT !!! MAKE COMMENTS AND PROVIDE A DETAILED DOCUMENTATION OF THE METHOD IMPLEMENTED!!! THANK YOU

 

Task: Reading and recording call events,

You will be required to follow all other aspects of the class design recipe.

To Do:  implement the process_event_history() function in the application module. The role of this function is to instantiate Call objects and store each of them in the right customer's records.

The parameter log is a dictionary containing all calls and SMSs from the dataset. Its key events contains a list of call and SMS events, which you will go through, creating Call objects out of events of type "call", and ignoring events of type "sms".

Each event you extract from the log dictionary is itself a dictionary. A call event has the following keys:

'type' corresponds to the type of event ("call" or "sms")
'src_number' corresponds to the caller's phone number
'dst_number' corresponds to the callee's phone number
'time' corresponds to the time when this call was made (for example: "2018-01-02 01:07:10")
'duration' corresponds to the call duration (in seconds)
'src_loc' corresponds to the caller's location (longitude+latitude)
'dst_loc' corresponds to the callee's location (longitude+latitude)
Provided the first three lines of code in this method, to show you how to extract data from the dictionary and to give you an example of using the datetime module. You will need to familiarize yourselves with this module by reading https://docs.python.org/3/library/datetime.html . As you go through the list of events and instantiate Call objects, you must also record these in the right Customer's records. This must be done by using the Customer class API, so please consult it to find the methods for registering incoming or outgoing calls. You will implement some of these Customer methods in the next task so calling them now will have no effect, but put the calls in. As we discussed in lectures, in order to use an API, all you need to know is the interface, not the implementation.

Additionally, as you instantiate new events, every time a new month is detected for the current event you are processing (whether it's a call or SMS!), you must advance all customers to a new month of contract. This is done using the new_month() function from the application.py module.

To help you understand this better, we define a few concepts which we will use in this assignment:

Advancing to a new month is the action of moving to a new month of contract, which must be done for the purposes of billing. The new_month() function in this module advances the month for every customer for each of their phonelines, according to the respective contract types (remember that customers can have multiple phone lines each, and that each phone line can be under a different type of contract).

Gap month is defined as a month with no activity for any customer (no calls or SMSs), despite there being activity in the month prior to the gap month, as well as in the month after the gap month.

We are making several simplifying assumptions, and enforcing them via preconditions in the code:

The input data is guaranteed to be sorted chronologically. Therefore, advancing to a new month of contract can be safely done. For example, once you encounter an event from February 2019, you are guaranteed the next events you process cannot be from a month before February 2019.

There is no gap month in the input data. This implies that for the timespan between the first event and the last event in the dataset, there is no month with zero activity from all customers. In other words, while one customer could have zero activity during a specific month X, there is at least one other customer who had some activity during that month. Therefore, according to the definition of advancing a month, customers with zero activity for a specific month will still get a Bill instance created. This bill will just have whatever baseline cost the corresponding contract specifies (more on this when we get to contracts in a later task).

Important: given find_customer_by_number() function. You must use it to figure out which customer a number belongs to.

Check your work: Write pytest tests to make sure your code so far works according to specifications. It is your responsibility to write good tests!

 

import datetime
import json

from contract import Contract
from customer import Customer
from phoneline import PhoneLine
from visualizer import Visualizer


def import_data() -> dict[str, list[dict]]:
    """ Open the file which stores the json data, and return
    a dictionary that stores this data in a format as described in the A1
    handout.

    Precondition: the dataset file must be in the json format.
    """
    with open("dataset.json") as o:
        log = json.load(o)
        return log


def create_customers(log: dict[str, list[dict]]) -> list[Customer]:
    """ Returns a list of Customer instances for each customer from the input
    dataset from the dictionary .

    Precondition:
    - The dictionary contains the input data in the correct format,
    matching the expected input format described in the handout.
    """
    customer_list = []
    for cust in log['customers']:
        customer = Customer(cust['id'])
        for line in cust['lines']:
            # TODO:
            # comment out the following three lines of code only when you get
            # to implement task 3. These lines are provided as a placeholder so
            # that your visualization works when you have only completed up to
            # and including task 2. Never instantiate the abstract class
            # "Contract" as below.
            # Remove this TODO list when you're done.
            contract = Contract(datetime.datetime.now())
            contract.new_month = lambda *args: None
            contract.bill_call = lambda *args: None
            # TODO:
            # 1) Uncomment the piece of code below once you've implemented
            #    all types of contracts.
            # 2) Make sure to import the necessary contract classes in this file
            #    and remove any unused imports to pass PyTA.
            # 3) Do not change anything in the code below besides uncommenting it
            # 4) Remove this TODO list when you're done.
            """
            contract = None
            if line['contract'] == 'prepaid':
                # start with $100 credit on the account
                contract = PrepaidContract(datetime.date(2017, 12, 25), 100)
            elif line['contract'] == 'mtm':
                contract = MTMContract(datetime.date(2017, 12, 25))
            elif line['contract'] == 'term':
                contract = TermContract(datetime.date(2017, 12, 25),
                                        datetime.date(2019, 6, 25))
            else:
                print("ERROR: unknown contract type")
            """

            line = PhoneLine(line['number'], contract)
            customer.add_phone_line(line)
        customer_list.append(customer)
    return customer_list

def find_customer_by_number(number: str, customer_list: list[Customer]) \
        -> Customer:
    """ Return the Customer with the phone number in the list of
    customers .
    If the number does not belong to any customer, return None.
    """
    cust = None
    for customer in customer_list:
        if number in customer:
            cust = customer
    return cust


def new_month(customer_list: list[Customer], month: int, year: int) -> None:
    """ Advance all customers in to a new month of their
    contract, as specified by the and arguments.
    """
    for cust in customer_list:
        cust.new_month(month, year)


def process_event_history(log: dict[str, list[dict]],
                          customer_list: list[Customer]) -> None:
    """ Process the calls from the dictionary. The
    list contains all the customers that exist in the dictionary.

    Construct Call objects from and register the Call into the
    corresponding customer's call history.

    Hint: You must advance all customers to a new month using the new_month()
    function, everytime a new month is detected for the current event you are
    extracting.

    Preconditions:
    - All calls are ordered chronologically (based on the call's date and time),
    when retrieved from the dictionary , as specified in the handout.
    - The argument guarantees that there is no "gap" month with zero
    activity for ALL customers, as specified in the handout.
    - The dictionary is in the correct format, as defined in the
    handout.
    - The already contains all the customers from the .
    """
    # TODO: Implement this method. We are giving you the first few lines of code
    billing_date = datetime.datetime.strptime(log['events'][0]['time'],
                                              "%Y-%m-%d %H:%M:%S")
    billing_month = billing_date.month
    # start recording the bills from this date
    # Note: uncomment the following lines when you're ready to implement this
    #
    # new_month(customer_list, billing_date.month, billing_date.year)
    #
    # for event_data in log['events']:
    #  
    # ...
 

SAMPLE DATA SET:

tiny_data = \
{"events": [
    {"type": "sms",
     "src_number": "422-4785",
     "dst_number": "731-0105",
     "time": "2018-01-01 14:29:05",
     "src_loc": [-79.42848154284123, 43.641401675960374],
     "dst_loc": [-79.52745693913239, 43.750338501653374]},
    {"type": "sms",
     "src_number": "934-0592",
     "dst_number": "136-5226",
     "time": "2018-01-02 03:17:57",
     "src_loc": [-79.45188229255568, 43.62186408875219],
     "dst_loc": [-79.36866519485261, 43.680793196449336]},
    {"type": "call",
     "src_number": "422-4785",
     "dst_number": "136-5226",
     "time": "2018-01-03 02:14:31",
     "duration": 117,
     "src_loc": [-79.68079993411648, 43.64986163420895],
     "dst_loc": [-79.46762523704258, 43.59568659654661]}
    ],
"customers": [
    {"lines": [{"number": "861-1710", "contract": "mtm"}], "id": 2247},
    {"lines": [{"number": "426-4804", "contract": "term"},
               {"number": "934-0592", "contract": "term"},
               {"number": "131-3768", "contract": "prepaid"},
               {"number": "386-6346", "contract": "term"}], "id": 3895},
    {"lines": [{"number": "931-8588", "contract": "term"},
               {"number": "981-7145", "contract": "mtm"},
               {"number": "817-5571", "contract": "mtm"},
               {"number": "581-0057", "contract": "mtm"},
               {"number": "452-7360", "contract": "prepaid"}], "id": 8548},
    {"lines": [{"number": "895-2223", "contract": "prepaid"},
               {"number": "425-5910", "contract": "mtm"},
               {"number": "731-0105", "contract": "term"},
               {"number": "136-5226", "contract": "mtm"},
               {"number": "422-4785", "contract": "prepaid"}], "id": 5716},
    {"lines": [{"number": "829-6467", "contract": "term"}], "id": 9701}
    ]

 }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image
Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Income Tax Fundamentals 2013

Authors: Gerald E. Whittenburg, Martha Altus Buller, Steven L Gill

31st Edition

1111972516, 978-1285586618, 1285586611, 978-1285613109, 978-1111972516

More Books

Students explore these related Programming questions