Пример #1
0
class Life:
    def __init__(self, start_time: int, family_range, friends_range,
                 coworkers_range, others_range):

        self.ONE_HOUR = 3600  # cannot be changed
        self.ONE_DAY = 86400

        self.family = get_handsets(family_range, 'family')
        self.friends = get_handsets(friends_range, 'friend')
        self.coworkers = get_handsets(coworkers_range, 'coworker')
        self.others = get_handsets(others_range, 'other')

        self.all_handsets = self.family + self.friends + self.coworkers + self.others  # noqa

        # this is the current date/time for the simulation
        self.time = start_time

        # save off the actual start time for reporting
        self.start_time_ts = start_time
        self.start_time = datetime.datetime.utcfromtimestamp(
            start_time).isoformat()  # noqa

        # the person that eventually will contract C19
        self.subject = Handset('subject')

        self.cloud = Cloud()

    def start(self):
        """This is the main entrypoint for running the simulation, the
        called functions here are just helpers to create common patterns
        of interaction
        """
        for _ in range(0, 5):
            self.weekday()

        self.weekend()
        self.weekend()

        for _ in range(0, 5):
            self.weekday()

        self.weekend()
        self.weekend()

        # save off the actual end time for reporting
        self.end_time = datetime.datetime.utcfromtimestamp(
            self.time).isoformat()  # noqa

        self.subject.upload_teks(self.cloud)

    def find_contacts(self):
        """Go through all of the handsets and find
        which ones were in contact
        """
        contacts = []
        for handset in self.all_handsets:
            contacts.append(handset.determine_contacts(self.cloud))
        return sorted(contacts, key=lambda c: len(c), reverse=True)

    def mingle(self, other: Handset):
        subject_rpi = self.subject.get_rpi(self.time)
        other_rpi = other.get_rpi(self.time)

        other.receive_rpi(subject_rpi)
        self.subject.receive_rpi(other_rpi)

    def generate_report(self):

        ts = datetime.datetime.utcfromtimestamp(self.start_time_ts)
        fname = 'report_' + ts.strftime('%Y-%m-%dT%H%M%S') + '.txt'

        # report statistics
        stats = {}
        stats['report_name'] = fname
        stats['start_time'] = self.start_time
        stats['end_time'] = self.end_time
        stats['hour_duration_sec'] = self.ONE_HOUR
        stats['day_duration_sec'] = self.ONE_DAY
        stats['contacts'] = 0
        stats['contact_periods'] = 0

        with open(fname, 'w') as fp:

            stats['family'] = len(self.family)
            stats['friends'] = len(self.friends)
            stats['coworkers'] = len(self.coworkers)
            stats['others'] = len(self.others)

            fp.write(f'Simulation Start Time: {self.start_time}\n\n')
            fp.write(f'Family Count: {len(self.family)}\n')
            fp.write(f'Friend Count: {len(self.friends)}\n')
            fp.write(f'Coworker Count: {len(self.coworkers)}\n')
            fp.write(f'Other Count: {len(self.others)}\n\n')

            contacts = self.find_contacts()
            contact_list: List[Contact]
            for contact_list in contacts:
                if not contact_list:
                    continue
                stats['contacts'] = stats['contacts'] + 1
                # write metadata about the handset using the first Contact
                fp.write('-' * 20 + '\n')
                fp.write(f'Handset ID: {contact_list[0].uuid}\n')
                fp.write(f'Relation to subject: {contact_list[0].relation}\n')
                fp.write(f'Contact periods:\n')
                # write out the timestamps this handset had close
                # contact with the subject
                for contact in contact_list:
                    fp.write(f'\t\t{contact.ts}\n')
                    stats['contact_periods'] = stats['contact_periods'] + 1

        return json.dumps(stats, sort_keys=False, indent=4)

    def hour(self, focus: str):

        self.time += self.ONE_HOUR

        if focus == 'family':
            other = random.choice(self.family)
            self.mingle(other)

        if focus == 'coworker':
            other = random.choice(self.coworkers)
            self.mingle(other)
            other = random.choice(self.coworkers)
            self.mingle(other)

        if focus == 'friends':
            other = random.choice(self.friends)
            self.mingle(other)

        if focus == 'others':
            other = random.choice(self.others)
            self.mingle(other)

    def weekday(self):
        day_start = self.time  # save the first hour of our day

        # starting a new day, generate the TEK
        # for each handset

        self.subject.create_tek(self.time)

        for h in self.all_handsets:
            h.create_tek(self.time)

        # 1h at home with family
        self.hour('family')

        # 1h commute / breakfast
        if random.choice([1, 2, 3]) == 1:
            self.hour('others')

        # 4h work
        self.hour('coworker')
        self.hour('coworker')
        self.hour('coworker')
        self.hour('coworker')

        # 1h lunch / gym
        if random.choice([1, 2, 3]) == 1:
            self.hour('others')

        # 4h work
        self.hour('coworker')
        self.hour('coworker')
        self.hour('coworker')
        self.hour('coworker')

        # 1h happy hour
        if random.choice([1, 2, 3, 4, 5]) == 1:
            self.hour('friends')

        # 2h back home
        self.hour('family')
        self.hour('family')

        # fast forward to the next morning
        self.time = day_start + self.ONE_DAY

    def weekend(self):
        day_start = self.time

        self.subject.create_tek(self.time)

        for h in self.all_handsets:
            h.create_tek(self.time)

        # 2h wakeup home
        self.hour('family')
        self.hour('family')

        # 1h gym
        self.hour('others')

        # 1h quick meetup
        self.hour('friends')

        # 2h lunch home
        self.hour('family')
        self.hour('family')

        # party
        self.hour('friends')
        self.hour('friends')

        # afterparty
        self.hour('others')
        self.hour('others')

        # 1h family
        self.hour('family')
        self.hour('family')

        self.time = day_start + self.ONE_DAY
Пример #2
0
    def mingle(self, other: Handset):
        subject_rpi = self.subject.get_rpi(self.time)
        other_rpi = other.get_rpi(self.time)

        other.receive_rpi(subject_rpi)
        self.subject.receive_rpi(other_rpi)
Пример #3
0
class Life:
    def __init__(self, start_time: int):
        self.family = get_handsets(random.randrange(2, 8), 'family')
        self.friends = get_handsets(random.randrange(10, 20), 'friend')
        self.coworkers = get_handsets(random.randrange(15, 40), 'coworker')
        self.others = get_handsets(random.randrange(40, 100), 'other')

        self.all_handsets = self.family + self.friends + self.coworkers + self.others  # noqa

        # this is the current date/time for the simulation
        self.time = start_time

        # save off the actual start time for reporting
        self.start_time = datetime.datetime.utcfromtimestamp(
            start_time).isoformat()  # noqa

        # the person that eventually will contract C19
        self.subject = Handset('subject')

        self.cloud = Cloud()

    def start(self):
        """This is the main entrypoint for running the simulation, the
        called functions here are just helpers to create common patterns
        of interaction
        """
        for _ in range(0, 5):
            self.weekday()

        self.weekend()
        self.weekend()

        for _ in range(0, 5):
            self.weekday()

        self.weekend()
        self.weekend()

        self.subject.upload_teks(self.cloud)

    def find_contacts(self):
        """Go through all of the handsets and find
        which ones were in contact
        """
        contacts = []
        for handset in self.all_handsets:
            contacts.append(handset.determine_contacts(self.cloud))
        return sorted(contacts, key=lambda c: len(c), reverse=True)

    def mingle(self, other: Handset):
        subject_rpi = self.subject.get_rpi(self.time)
        other_rpi = other.get_rpi(self.time)

        other.receive_rpi(subject_rpi)
        self.subject.receive_rpi(other_rpi)

    def generate_report(self):
        with open('report.txt', 'w') as fp:
            fp.write(f'Simulation Start Time: {self.start_time}\n\n')
            fp.write(f'Family Count: {len(self.family)}\n')
            fp.write(f'Friend Count: {len(self.friends)}\n')
            fp.write(f'Coworker Count: {len(self.coworkers)}\n')
            fp.write(f'Other Count: {len(self.others)}\n\n')

            contacts = self.find_contacts()
            contact_list: List[Contact]
            for contact_list in contacts:
                if not contact_list:
                    continue
                # write metadata about the handset using the first Contact
                fp.write('-' * 20 + '\n')
                fp.write(f'Handset ID: {contact_list[0].uuid}\n')
                fp.write(
                    f'Relation to subject: {contact_list[0].relation} [SIMULATION DATA ONLY, would not be revealed real-world] \n'
                )  # noqa
                fp.write(f'Contact periods:\n')
                # write out the timestamps this handset had close
                # contact with the subject
                for contact in contact_list:
                    fp.write(f'\t\t{contact.ts}\n')

    def hour(self, focus: str):

        self.time += ONE_HOUR

        if focus == 'family':
            other = random.choice(self.family)
            self.mingle(other)

        if focus == 'coworker':
            other = random.choice(self.coworkers)
            self.mingle(other)
            other = random.choice(self.coworkers)
            self.mingle(other)

        if focus == 'friends':
            other = random.choice(self.friends)
            self.mingle(other)

        if focus == 'others':
            other = random.choice(self.others)
            self.mingle(other)

    def weekday(self):
        day_start = self.time  # save the first hour of our day

        # starting a new day, generate the TEK
        # for each handset

        self.subject.create_tek(self.time)

        for h in self.all_handsets:
            h.create_tek(self.time)

        # spend a couple hours in the morning with family
        self.hour('family')
        self.hour('family')

        # stop for some breakfast / coffee on the way to work?
        if random.choice([1, 2, 3]) == 1:
            self.hour('others')

        # work, work!
        self.hour('coworker')
        self.hour('coworker')
        self.hour('coworker')

        # lunch / gym?
        if random.choice([1, 2, 3]) == 1:
            self.hour('others')

        # moar work
        self.hour('coworker')
        self.hour('coworker')

        # happy hour?
        if random.choice([1, 2, 3, 4, 5]) == 1:
            self.hour('friends')

        # back home
        self.hour('family')
        self.hour('family')

        # fast forward to the next morning
        self.time = day_start + ONE_DAY

    def weekend(self):
        day_start = self.time

        self.subject.create_tek(self.time)

        for h in self.all_handsets:
            h.create_tek(self.time)

        self.hour('family')
        self.hour('family')
        self.hour('family')

        # errands or whatever
        self.hour('others')

        # quick meetup
        self.hour('friends')

        # back home
        self.hour('family')
        self.hour('family')

        # party!
        self.hour('friends')
        self.hour('friends')
        self.hour('friends')

        # afterparty
        self.hour('others')
        self.hour('others')

        self.time = day_start + ONE_DAY