Question
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
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
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
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
contract, as specified by the
"""
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
list contains all the customers that exist in the
Construct Call objects from
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
- The
activity for ALL customers, as specified in the handout.
- The
handout.
- 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
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started