Write a function potential_contacts(person_a, person_b)
that identifies all of the potential contacts between two people, given data on their movement over multiple days.
The function takes the following arguments,
person_a
person_b
,
which are each lists of visits by the two people, with each visit formatted as a 7-tuple
as described above.
The function should return a tuple
consisting of:
- a
set
of potential contact locations and times for these two people, each in the form of a 6-tuple
(see below; note that the order of the items in thisset
does not matter, as aset
does not store order); and - a 2-
tuple
containing a pair ofinteger
values (hours and minutes) corresponding to the total duration of potential contact between these two people.
Note that each the potential contact locations and time in the returned set
is a 6-tuple
rather than a 7-tuple
because it will not include the ID of an individual. It also differs from the 7-tuple
described above in that the times referred to, are not the time at which a person arrived at and departed from a location, but rather the time at which the two people started being at the same location (ie, when the second person arrive) and the time at which the two people stopped being at the same location (ie, when the first person left).
For example, if the original visit 7-tuples
were:
("Natalya", "Nutrity", 2, 10, 10, 11, 45)
and:
("Chihiro", "Nutrity", 2, 9, 45, 11, 30)
then the 6-tuple
corresponding to the potential contact between Natalya and Chihiro would be:
("Nutrify", 2, 10, 10, 11, 30)
indicating that they were both located at Nutrity on the second day of the outbreak between 10:10am and 11:30am.
Assumptions:
- You can assume that the input arguments are syntactically correct given the definitions and assumptions on this slide and on previous slides.
- Any invalid visits should be ignored. Contact locations and times should only be generated for pairs of valid visits.
Here are some example calls to your function:
>>> potential_contacts([('Russel', 'Foodigm', 2, 9, 0, 10, 0), ('Russel', 'Afforage', 2, 10, 0, 11, 30), ('Russel', 'Nutrity', 2, 11, 45, 12, 0), ('Russel', 'Liberry', 3, 13, 0, 14, 15)], [('Natalya', 'Afforage', 2, 8, 15, 10, 0), ('Natalya', 'Nutrity', 4, 10, 10, 11, 45)])
(set(), (0, 0))
>>> potential_contacts([('Russel', 'Foodigm', 2, 9, 0, 10, 0), ('Russel', 'Afforage', 2, 10, 0, 11, 30), ('Russel', 'Nutrity', 2, 11, 45, 12, 0), ('Russel', 'Liberry', 3, 13, 0, 14, 15)], [('Chihiro', 'Foodigm', 2, 9, 15, 9, 30), ('Chihiro', 'Nutrity', 4, 9, 45, 11, 30), ('Chihiro', 'Liberry', 3, 12, 15, 13, 25)])
({('Foodigm', 2, 9, 15, 9, 30), ('Liberry', 3, 13, 0, 13, 25)}, (0, 40))
>>> potential_contacts([('Natalya', 'Afforage', 2, 8, 15, 10, 0), ('Natalya', 'Nutrity', 4, 10, 10, 11, 45)], [('Chihiro', 'Foodigm', 2, 9, 15, 9, 30), ('Chihiro', 'Nutrity', 4, 9, 45, 11, 30), ('Chihiro', 'Liberry', 3, 12, 15, 13, 25)])
({('Nutrity', 4, 10, 10, 11, 30)}, (1, 20))
>>> potential_contacts([('Russel', 'Foodigm', 2, 9, 0, 10, 0), ('Russel', 'Afforage', 2, 10, 0, 11, 30), ('Russel', 'Nutrity', 2, 11, 45, 12, 0), ('Russel', 'Liberry', 3, 13, 0, 14, 15)], []) # person with no visits
(set(), (0, 0))
code:
def add_time(hour1, minute1, hour2, minute2): total_minute = minute1 + minute2 # add minutes total_hour = hour1 + hour2 # add hours # if total_minutes>= 60 then total_minutes mod 60 will return total minutes and total_minutes//60+total_hour give total hours total_hour, total_minute = (total_hour + (total_minute // 60), total_minute % 60) if total_minute >= 60 else ( total_hour, total_minute) return (total_hour, total_minute) # Function to convert time to minutes so that we can compare time easily def convert_to_minutes(hour, minute): return int(hour) * 60 + int(minute) def potential_contacts(person_a, person_b): output_set = set() total_duration = [0, 0] # initilaize empty list to add duration for which 2 person were at same place at same time if not person_a or not person_b: # check if any of the person has no visits then return empty set and time duration (0,0) as both person will not meet return (output_set, (0, 0)) else: for a in person_a: # iterate through person1 visits for b in person_b: # iterate through person2 visits output_tup = [] # initialize an empty list if a[1] == b[1] and a[2] == b[2]: # check if location and day is same of both the persons # if a arrived when B is leaving or has left and vice versa then they will not meet so put not in condition so that scenario where they will meet will be considered if not convert_to_minutes(a[3], a[4]) >= convert_to_minutes(b[5], b[6]) and not convert_to_minutes( b[3], b[4]) >= convert_to_minutes(a[5], a[6]): # choose the time at which the two people started being at the same location i.e when the second person arrive start_hour, start_minutes = (a[3], a[4]) if convert_to_minutes(a[3], a[4]) > convert_to_minutes( b[3], b[4]) else (b[3], b[4]) # choose the time at which the two people stopped being at the same location (ie, when the first person left) end_hour, end_minutes = (a[5], a[6]) if convert_to_minutes(a[5], a[6]) < convert_to_minutes( b[5], b[6]) else (b[5], b[6]) # add location,day,time when they were at same location and time at which they stopped being at same place to the list output_tup.extend((a[1], a[2], start_hour, start_minutes, end_hour, end_minutes)) # convert the list to tuple and add it to output set output_set.add(tuple(output_tup)) # add new time 2 person were at same place to duration they were together at same place in earlier visit total_hour, total_minute = add_time(total_duration[0], total_duration[1], end_hour - start_hour, end_minutes - start_minutes) total_duration[0], total_duration[1] = (total_hour, total_minute) return (output_set, tuple(total_duration))