-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapplication.py
More file actions
190 lines (155 loc) · 7.27 KB
/
Copy pathapplication.py
File metadata and controls
190 lines (155 loc) · 7.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import datetime
import json
from contract import MTMContract, PrepaidContract, TermContract
from customer import Customer
from phoneline import PhoneLine
from visualizer import Visualizer
from call import Call
def import_data() -> dict[str, list[dict]]:
""" Open the file <dataset.json> 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 <log>.
Precondition:
- The <log> 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']:
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 <number> in the list of
customers <customer_list>.
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 <customer_list> to a new month of their
contract, as specified by the <month> and <year> 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 <log> dictionary. The <customer_list>
list contains all the customers that exist in the <log> dictionary.
Construct Call objects from <log> 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 <log>, as specified in the handout.
- The <log> argument guarantees that there is no "gap" month with zero
activity for ALL customers, as specified in the handout.
- The <log> dictionary is in the correct format, as defined in the
handout.
- The <customer_list> already contains all the customers from the <log>.
"""
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']:
# check for a new month and advance
if billing_month != datetime.datetime.strptime(
event_data['time'], "%Y-%m-%d %H:%M:%S").month:
billing_month = datetime.datetime.strptime(
event_data['time'], "%Y-%m-%d %H:%M:%S").month
new_month(customer_list, billing_month, billing_date.year)
# if the event is a call make a call object from the data
if event_data["type"] == "call":
time = datetime.datetime.strptime(event_data['time'],
"%Y-%m-%d %H:%M:%S")
call = Call(event_data["src_number"], event_data["dst_number"],
time, event_data["duration"],
tuple(event_data["src_loc"]),
tuple(event_data["dst_loc"]))
# register call into customer history (incoming/outgoing)
src_cust = find_customer_by_number(event_data["src_number"],
customer_list)
dst_cust = find_customer_by_number(event_data["dst_number"],
customer_list)
src_cust.make_call(call)
dst_cust.receive_call(call)
if __name__ == '__main__':
v = Visualizer()
print("Toronto map coordinates:")
print(" Lower-left corner: -79.697878, 43.576959")
print(" Upper-right corner: -79.196382, 43.799568")
input_dictionary = import_data()
customers = create_customers(input_dictionary)
process_event_history(input_dictionary, customers)
# ----------------------------------------------------------------------
# NOTE: You do not need to understand any of the implementation below,
# to be able to solve this assignment. However, feel free to
# read it anyway, just to get a sense of how the application runs.
# ----------------------------------------------------------------------
# Gather all calls to be drawn on screen for filtering, but we only want
# to plot each call only once, so only plot the outgoing calls to screen.
# (Each call is registered as both an incoming and outgoing)
all_calls = []
for c in customers:
hist = c.get_history()
all_calls.extend(hist[0])
print("\n-----------------------------------------")
print("Total Calls in the dataset:", len(all_calls))
# Main loop for the application.
# 1) Wait for user interaction with the system and processes everything
# appropriately
# 2) Take the calls from the results of the filtering and create the
# drawables and connection lines for those calls
# 3) Display the calls in the visualization window
events = all_calls
while not v.has_quit():
events = v.handle_window_events(customers, events)
connections = []
drawables = []
for event in events:
connections.append(event.get_connection())
drawables.extend(event.get_drawables())
# Put the connections on top of the other sprites
drawables.extend(connections)
v.render_drawables(drawables)
import python_ta
python_ta.check_all(config={
'allowed-import-modules': [
'python_ta', 'typing', 'json', 'datetime',
'visualizer', 'customer', 'call', 'contract', 'phoneline'
],
'allowed-io': [
'create_customers', 'import_data'
],
'generated-members': 'pygame.*'
})