Example #1
0
    def phone_call_connect(self):

        # speak to someone - go from here to a more complex assist/outcome section
        called_at = self.env.now

        # at this time/date what type of adviser is available?
        # is one of these types available?
        adviser = self.adviser_check(called_at)

        current_ad = yield self.rep.adviser_store.get(lambda item: item.type == adviser)
        wait_time = self.env.now - called_at

        # renege time a fixed value for now. Determine suitable distribution from paradata or call centre MI.
        if wait_time >= self.input_data["renege"]:
            # hang up

            if oo.record_call_renege:
                self.output_data['Call_renege'].append(oo.generic_output(self.rep.reps,
                                                                         self.district.district,
                                                                         self.la,
                                                                         self.lsoa,
                                                                         self.digital,
                                                                         self.hh_type,
                                                                         self.hh_id,
                                                                         self.env.now))

            self.rep.adviser_store.put(current_ad)

            # record wait times for stats generation - wait time her eis how long they would of had to wait
            # not how long they did wait - this is given by the renege time
            if wait_time > 0:
                self.record_wait_time(wait_time, self.input_data["renege"])

            # so hh didn't get through - some may now respond with no extra tries but more will call again or give up.
            action = self.action_test("renege")
            # but when?
            if not action[0] == "Do nothing":
                function_to_call = getattr(self, action[0])
                yield self.env.timeout(action[1])
                yield self.env.process(function_to_call())

        else:
            # got through
            if oo.record_call_contact:
                self.output_data['Call_contact'].append(oo.generic_output(self.rep.reps,
                                                                          self.district.district,
                                                                          self.la,
                                                                          self.lsoa,
                                                                          self.digital,
                                                                          self.hh_type,
                                                                          self.hh_id,
                                                                          self.env.now))

            if wait_time > 0:
                self.record_wait_time(wait_time, self.input_data["renege"])

            yield self.env.process(self.phone_call_assist(current_ad))
Example #2
0
    def phone_call_assist(self, current_ad):

        da_test = self.rnd.uniform(0, 100)
        # how effective current adviser type at conversion to digital
        da_effectiveness = current_ad.input_data['da_effectiveness'][self.hh_type]

        # wait to determine if digital or paper preference
        yield self.env.timeout(current_ad.input_data['call_times']['query'] / 60)

        if self.digital or self.paper_allowed:
            # no need to persuade go straight to the outcome
            yield self.rep.env.process(self.phone_call_outcome(current_ad))

        elif not self.digital and da_test <= da_effectiveness:
            # not digital and adviser converts household to digital but takes some time
            yield self.env.timeout(current_ad.input_data['call_times']['convert'] / 60)

            # record event
            if oo.record_call_convert:
                self.rep.output_data['Call_convert'].append(oo.generic_output(self.rep.reps,
                                                                              self.district.district,
                                                                              self.la,
                                                                              self.lsoa,
                                                                              self.digital,
                                                                              self.hh_type,
                                                                              self.hh_id,
                                                                              self.rep.env.now))

            self.digital = True
            yield self.env.process(self.phone_call_outcome(current_ad))

        elif not self.digital and da_test > da_effectiveness:
            # not digital and not converted so arrange a visit or something else when we know what!

            yield self.env.timeout(current_ad.input_data['call_times']['failed'] / 60)

            if oo.record_call_request:
                self.rep.output_data['Call_request'].append(oo.generic_output(self.rep.reps,
                                                                              self.district.district,
                                                                              self.la,
                                                                              self.lsoa,
                                                                              self.digital,
                                                                              self.hh_type,
                                                                              self.hh_id,
                                                                              self.env.now))

            # up priority and tag so a visit happens at time likely time to be in - or just set it to succeed - or both?
            self.priority -= 10

            self.rep.adviser_store.put(current_ad)
            # self.arranged_visit = True  # basically has requested a visit so go at optimal time and move to front..
            self.arranged_visit = False
Example #3
0
    def action(self):
        # directs the household to follow the COA set on initialisation at the relevant time

        yield self.env.timeout(self.initial_time)

        if self.initial_status == 'late' and not self.return_sent:
            # normal response
            yield self.env.process(self.household_returns(self.calc_delay()))

        elif self.initial_status == 'help' and not self.return_sent:
            # help
            yield self.env.process(self.contact())

        else:
            # nowt
            if oo.record_do_nothing:
                self.output_data['Do_nothing'].append(oo.generic_output(self.rep.reps,
                                                                        self.district.district,
                                                                        self.la,
                                                                        self.lsoa,
                                                                        self.digital,
                                                                        self.hh_type,
                                                                        self.hh_id,
                                                                        self.env.now))
        yield self.env.timeout(0)  # do nothing more
Example #4
0
def schedule_paper_drop(obj, contact_type, reminder_type, delay):

    # add to summary of paper given out
    if reminder_type == 'pq' and oo.record_paper_summary:

        for key, value in obj.rep.paper_summary.items():
            value[str(getattr(obj,
                              key))][math.floor(obj.rep.env.now / 24)] += 1

        for key, value in obj.rep.paper_totals.items():
            value[str(getattr(obj, key))] += 1

    output_type = contact_type + "_" + reminder_type + "_posted"  # use this as output key

    if oo.record_posted:
        obj.rep.output_data[output_type].append(
            oo.generic_output(obj.rep.reps, obj.district.district, obj.la,
                              obj.lsoa, obj.digital, obj.hh_type, obj.hh_id,
                              obj.env.now))

    if delay > 0:
        start_delayed(obj.env, obj.receive_reminder(reminder_type), delay)
    else:
        obj.env.process(obj.receive_reminder(reminder_type))

    yield obj.env.timeout(0)
Example #5
0
def ret_rec(household, rep):
    # print out every 100000 returns?
    #if rep.total_responses % 100000 == 0:
    #print(rep.total_responses)

    if oo.record_active_summary:
        # add household to summary of responses
        for key, value in rep.active_summary.items():
            value[str(getattr(household,
                              key))][math.floor(rep.env.now / 24)] += 1

        for key, value in rep.active_totals.items():
            value[str(getattr(household, key))] += 1

    if oo.record_active_paper_summary and not household.digital:

        for key, value in rep.active_paper_summary.items():
            value[str(getattr(household,
                              key))][math.floor(rep.env.now / 24)] += 1

        for key, value in rep.active_paper_totals.items():
            value[str(getattr(household, key))] += 1

    household.return_received = True
    if oo.record_return_received:
        rep.output_data['Return_received'].append(
            oo.generic_output(rep.reps, household.district.district,
                              household.la, household.lsoa, household.digital,
                              household.hh_type, household.hh_id, rep.env.now))
    # currently every return gets counted as a response as soon as it is received - this may need to change
    household.responded = True
    rep.total_responses += 1
    household.district.total_responses += 1

    # check size of output data - if over an amount, size or length write to file?
    if oo.record_responded:
        rep.output_data['Responded'].append(
            oo.generic_output(rep.reps, household.district.district,
                              household.la, household.lsoa, household.digital,
                              household.hh_type, household.hh_id, rep.env.now))

    # checks size of output and writes to file if too large
    if (h.dict_size(rep.output_data)) > rep.max_output_file_size:
        h.write_output(rep.output_data, rep.output_path, rep.run)

    yield rep.env.timeout(0)
Example #6
0
    def co_send_letter(self, household, letter_type, delay):
        if oo.record_letters:
            self.rep.output_data[letter_type + '_sent'].append(
                oo.generic_output(self.rep.reps, household.district.district,
                                  household.la, household.lsoa,
                                  household.digital, household.hh_type,
                                  household.hh_id, self.env.now))

        yield self.env.timeout(delay)
        self.env.process(household.receive_reminder(letter_type))
    def non_response(self):

        for household in self.households:
            if not household.return_sent:
                if oo.record_non_response:
                    self.rep.output_data['Non_response'].append(
                        oo.generic_output(self.rep.reps, self.district,
                                          household.la, household.lsoa,
                                          household.digital, household.hh_type,
                                          household.hh_id, self.env.now))
        yield self.env.timeout(0)
Example #8
0
    def phone_call(self):

        if oo.record_call:
            self.output_data['Call'].append(oo.generic_output(self.rep.reps,
                                                              self.district.district,
                                                              self.la,
                                                              self.lsoa,
                                                              self.digital,
                                                              self.hh_type,
                                                              self.hh_id,
                                                              self.env.now))
        self.calls += 1

        if (not self.digital and not self.paper_allowed and
            h.responses_to_date(self.district) < self.district.input_data['paper_trigger'] and self.paper_on_request):
            # so provide paper if the conditions are met...

            self.paper_allowed = True
            self.priority += 5  # lower the priority as more likely to reply
            # call to ask so may need to up the level of response above default here? Extra optional variable?
            yield self.env.process(hq.schedule_paper_drop(self, 'Call', 'pq', self.district.postal_delay))

        elif isinstance(self.adviser_check(self.env.now), str):
            # otherwise carry on to the call centre to speak to an adviser
            # unless outside times advisers are available - use check times and if none returned gracefully defer
            yield self.env.process(self.phone_call_connect())

        else:
            # no one available - gracefully defer - some will call back again?
            if oo.record_call_defer:
                self.output_data['Call_defer'].append(oo.generic_output(self.rep.reps,
                                                                        self.district.district,
                                                                        self.la,
                                                                        self.lsoa,
                                                                        self.digital,
                                                                        self.hh_type,
                                                                        self.hh_id,
                                                                        self.env.now))
Example #9
0
    def phone_call_outcome(self, current_ad):

        # digital by this point so just can you convince them to reply?
        outcome_test = self.rnd.uniform(0, 100)
        conversion_dict = self.input_data['success_rate'][str(h.current_day(self))]

        if outcome_test <= conversion_dict[h.return_time_key(conversion_dict, self.env.now)]:

            yield self.env.timeout(current_ad.input_data['call_times']['success'] / 60)

            if oo.record_call_success:
                self.rep.output_data['Call_success'].append(oo.generic_output(self.rep.reps,
                                                                              self.district.district,
                                                                              self.la,
                                                                              self.lsoa,
                                                                              self.digital,
                                                                              self.hh_type,
                                                                              self.hh_id,
                                                                              self.env.now))
            self.resp_planned = True
            self.rep.adviser_store.put(current_ad)
            self.rep.env.process(self.household_returns(self.calc_delay()))

        else:

            yield self.env.timeout(current_ad.input_data['call_times']['failed'] / 60)

            if oo.record_call_failed:
                self.rep.output_data['Call_failed'].append(oo.generic_output(self.rep.reps,
                                                                             self.district.district,
                                                                             self.la,
                                                                             self.lsoa,
                                                                             self.digital,
                                                                             self.hh_type,
                                                                             self.hh_id,
                                                                             self.env.now))
            self.rep.adviser_store.put(current_ad)
Example #10
0
    def household_returns(self, delay=0):
        """represents the hh returning their form - not the return being counted as a response by census"""

        if not self.return_sent:

            self.return_sent = True
            self.resp_time = self.env.now
            # add to hh response event log
            if oo.record_return_sent:
                self.output_data['Return_sent'].append(oo.generic_output(self.rep.reps,
                                                                         self.district.district,
                                                                         self.la,
                                                                         self.lsoa,
                                                                         self.digital,
                                                                         self.hh_type,
                                                                         self.hh_id,
                                                                         self.resp_time))

            if self.calc_delay() == 0:  # digital
                self.env.process(hq.ret_rec(self, self.rep))
            else:  # paper
                start_delayed(self.env, hq.ret_rec(self, self.rep), delay)

            yield self.env.timeout(0)  # hh does no more (without intervention)
Example #11
0
    def fu_visit_outcome(self, household):

        household_returns = self.household_test(household, "success_rate")

        if not household.return_sent and household_returns:
            # hh have not responded yet and respond there and then either by paper or digital.
            if oo.record_visit_success:
                self.rep.output_data['Visit_success'].append(
                    oo.visit_output(self.rep.reps, self.district.district,
                                    household.la, household.lsoa,
                                    household.digital, household.hh_type,
                                    household.hh_id, household.visits,
                                    self.env.now))

            household.resp_planned = True

            yield self.rep.env.process(
                household.household_returns(household.calc_delay()))

            time_worked = self.input_data['visit_times']['success'] / 60 + \
                          self.district.travel_dist / self.input_data["travel_speed"]

            if oo.record_time_summary:
                for key, value in self.rep.time_summary.items():
                    value[str(getattr(household, key))][math.floor(
                        self.rep.env.now / 24)] += time_worked

                for key, value in self.rep.time_totals.items():
                    value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)

        elif (not household.return_sent and not household_returns
              and h.responses_to_date(
                  self.district) < self.district.input_data['paper_trigger']
              and household.visits == household.input_data['max_visits']
              and h.str2bool(household.input_data['paper_after_max_visits'])
              and not household.paper_allowed):
            # hh have not responded but do not respond as a result of the visit.
            # need extra here for when you fail but not at max visits?
            if oo.record_visit_failed:
                self.rep.output_data['Visit_failed'].append(
                    oo.generic_output(self.rep.reps,
                                      household.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))
            # leave paper in hope they respond?
            household.paper_allowed = True
            hq.schedule_paper_drop(household, 'Visit', 'pq', self.has_pq)

            if oo.record_paper_summary:
                # add to the summary of the amount of paper given

                for key, value in self.rep.paper_summary.items():
                    value[str(getattr(household, key))][0] += 1

                for key, value in self.rep.paper_totals.items():
                    value[str(getattr(household, key))] += 1

            time_worked = self.input_data['visit_times']['failed'] / 60 + \
                          self.district.travel_dist / self.input_data["travel_speed"]

            for key, value in self.rep.time_summary.items():
                value[str(getattr(household, key))][math.floor(
                    self.rep.env.now / 24)] += time_worked

            for key, value in self.rep.time_totals.items():
                value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)

        elif not household.return_sent and not household_returns:
            # failed but no max visits so do no more
            if oo.record_visit_failed:
                self.rep.output_data['Visit_failed'].append(
                    oo.generic_output(self.rep.reps,
                                      household.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))

            time_worked = self.input_data['visit_times']['failed'] / 60 + \
                              self.district.travel_dist / self.input_data["travel_speed"]

            if oo.record_time_summary:

                for key, value in self.rep.time_summary.items():
                    value[str(getattr(household, key))][math.floor(
                        self.rep.env.now / 24)] += time_worked

                for key, value in self.rep.time_totals.items():
                    value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)
Example #12
0
    def fu_visit_assist(self, household):

        da_test = self.rnd.uniform(0, 100)
        da_effectiveness = self.input_data['da_effectiveness'][
            household.hh_type]

        time_worked = self.input_data['visit_times']['query'] / 60

        if oo.record_time_summary:

            for key, value in self.rep.time_summary.items():
                value[str(getattr(household, key))][math.floor(
                    self.rep.env.now / 24)] += time_worked

            for key, value in self.rep.time_totals.items():
                value[str(getattr(household, key))] += time_worked

        yield self.rep.env.timeout(time_worked)

        # if digital, have already responded or can use paper skip straight to the outcome of the visit
        if household.digital or household.return_sent or household.paper_allowed:
            yield self.rep.env.process(self.fu_visit_outcome(household))

        # if not digital try to persuade them to complete online.
        elif not household.digital and da_test <= da_effectiveness:

            time_worked = self.input_data['visit_times']['convert'] / 60

            if oo.record_time_summary:

                for key, value in self.rep.time_summary.items():
                    value[str(getattr(household, key))][math.floor(
                        self.rep.env.now / 24)] += time_worked

                for key, value in self.rep.time_totals.items():
                    value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)

            household.digital = True
            if oo.record_visit_convert:
                self.rep.output_data['Visit_convert'].append(
                    oo.generic_output(self.rep.reps,
                                      household.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))

            yield self.rep.env.process(self.fu_visit_outcome(household))

        # not digital, do not convince to go online but allowed to use paper so go to outcome
        elif not household.digital and da_test > da_effectiveness and household.paper_allowed:
            yield self.rep.env.process(self.fu_visit_outcome(household))

        # if not digital, do not convince to complete online, and trigger and max visits not reached give paper if on.
        elif (not household.digital and da_test > da_effectiveness
              and h.responses_to_date(
                  self.district) < self.district.input_data['paper_trigger']
              and household.visits == household.input_data['max_visits']
              and h.str2bool(household.input_data['paper_after_max_visits'])):

            household.paper_allowed = True
            self.env.process(
                hq.schedule_paper_drop(household, 'Visit', 'pq', self.has_pq))

            time_worked = self.input_data['visit_times']['paper'] / 60 +\
                          self.district.travel_dist/self.input_data["travel_speed"]

            if oo.record_time_summary:

                for key, value in self.rep.time_summary.items():
                    value[str(getattr(household, key))][math.floor(
                        self.rep.env.now / 24)] += time_worked

                for key, value in self.rep.time_totals.items():
                    value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)

        else:
            # or suggest other forms of assistance to be decided...
            # non implemented at present so another visit will be scheduled.
            if oo.record_visit_assist:
                self.rep.output_data['Visit_assist'].append(
                    oo.generic_output(self.rep.reps, self.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))

            time_worked = self.input_data['visit_times']['paper'] / 60 + \
                          self.district.travel_dist / self.input_data["travel_speed"]

            if oo.record_time_summary:

                for key, value in self.rep.time_summary.items():
                    value[str(getattr(household, key))][math.floor(
                        self.rep.env.now / 24)] += time_worked

                for key, value in self.rep.time_totals.items():
                    value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)
Example #13
0
    def fu_visit_contact(self, household):

        household.priority += 1  # automatically lower the priority of this hh after a visit
        household.visits += 1

        if oo.record_visit_summary:

            for key, value in self.rep.visit_summary.items():
                value[str(getattr(household, key))][math.floor(
                    self.rep.env.now / 24)] += 1

            for key, value in self.rep.visit_totals.items():
                value[str(getattr(household, key))] += 1

        if oo.record_visit:
            self.rep.output_data['Visit'].append(
                oo.visit_output(self.rep.reps, self.district.district,
                                household.la, household.lsoa,
                                household.digital, household.hh_type,
                                household.hh_id, household.visits,
                                self.env.now))

        if household.responded:
            if oo.record_visit_wasted:
                self.rep.output_data['Visit_wasted'].append(
                    oo.generic_output(self.rep.reps, self.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))

        elif household.resp_planned:
            if oo.record_visit_unnecessary:
                self.rep.output_data['Visit_unnecessary'].append(
                    oo.generic_output(self.rep.reps, self.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))

        household_is_in = self.household_test(household, "contact_rate")

        if household_is_in:
            if oo.record_visit_contact:
                self.rep.output_data['Visit_contact'].append(
                    oo.generic_output(self.rep.reps, self.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))

            # household.visits_contacted += 1
            yield self.rep.env.process(self.fu_visit_assist(household))

        elif (not household_is_in
              and household.visits == household.input_data['max_visits']
              and h.str2bool(household.input_data['paper_after_max_visits'])):

            household.paper_allowed = True
            hq.schedule_paper_drop(household, 'Visit', 'pq', self.has_pq)

            time_worked = self.input_data["visit_times"]["out_paper"] / 60 +\
                          self.district.travel_dist / self.input_data["travel_speed"]

            if oo.record_time_summary:

                for key, value in self.rep.time_summary.items():
                    value[str(getattr(household, key))][math.floor(
                        self.rep.env.now / 24)] += time_worked

                for key, value in self.rep.time_totals.items():
                    value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)

        else:
            # out - add drop off of a note
            if oo.record_visit_out:
                self.rep.output_data['Visit_out'].append(
                    oo.generic_output(self.rep.reps, self.district.district,
                                      household.la, household.lsoa,
                                      household.digital, household.hh_type,
                                      household.hh_id, self.env.now))

            self.env.process(
                hq.schedule_paper_drop(household, 'Visit', 'postcard',
                                       self.has_postcard))

            time_worked = self.input_data["visit_times"][
                "out"] / 60 + self.district.travel_dist / self.input_data[
                    "travel_speed"]

            if oo.record_time_summary:

                for key, value in self.rep.time_summary.items():
                    value[str(getattr(household, key))][math.floor(
                        self.rep.env.now / 24)] += time_worked

                for key, value in self.rep.time_totals.items():
                    value[str(getattr(household, key))] += time_worked

            yield self.rep.env.timeout(time_worked)
    def create_households(self):

        list_of_hh_types = sorted(list(self.input_data['households'].keys()))
        for hh_type in list_of_hh_types:

            # get hh data for current type
            hh_input_data = self.input_data['households'][hh_type]

            for i in range(hh_input_data['number']):

                # if allowed paper use different paper prop to if not...
                if h.str2bool(hh_input_data['paper_allowed']):
                    paper_prop = hh_input_data['paper_prop_pf']
                else:
                    paper_prop = hh_input_data['paper_prop_df']

                # set if digital here?
                hh_digital = h.set_preference(paper_prop, self.rnd)

                # define where the hh is located
                hh_geog = self.return_household_geog(
                    hh_input_data['cca_makeup'], hh_type, hh_digital)

                self.total_households += 1

                # determine initial HH action
                hh_action = self.initial_action(hh_input_data,
                                                self.first_interaction,
                                                hh_type, hh_geog, hh_digital)

                if hh_action.digital:
                    time_to_use = hh_action.time + hh_input_data['delay'][
                        'digital']
                else:
                    time_to_use = hh_action.time + hh_input_data['delay'][
                        'paper']

                if h.str2bool(hh_input_data['paper_allowed']
                              ) and oo.record_paper_summary:
                    # add to the summary of the amount of paper given

                    for key, value in self.rep.paper_summary.items():
                        value[str(getattr(hh_geog, key))][0] += 1

                    for key, value in self.rep.paper_totals.items():
                        value[str(getattr(hh_geog, key))] += 1

                if hh_action.type == 'early':
                    # don't need an instance of a household just directly record response/return at correct time

                    self.rep.total_responses += 1
                    self.total_responses += 1
                    if oo.record_responded:
                        self.rep.output_data['Return_sent'].append(
                            oo.generic_output(self.rep.reps, self.district,
                                              hh_geog.la, hh_geog.lsoa,
                                              hh_action.digital, hh_type,
                                              self.rep.total_hh,
                                              hh_action.time))

                    if oo.record_return_received:
                        self.rep.output_data['Return_received'].append(
                            oo.generic_output(self.rep.reps, self.district,
                                              hh_geog.la, hh_geog.lsoa,
                                              hh_action.digital, hh_type,
                                              self.rep.total_hh, time_to_use))

                    # add household to summary of total responses
                    if oo.record_active_summary:

                        for key, value in self.rep.active_summary.items():
                            value[str(getattr(hh_geog, key))][math.floor(
                                time_to_use / 24)] += 1

                        for key, value in self.rep.active_totals.items():
                            value[str(getattr(hh_geog, key))] += 1

                    # if paper and early also need to record???
                    if oo.record_active_paper_summary and not hh_action.digital:

                        for key, value in self.rep.active_paper_summary.items(
                        ):
                            value[str(getattr(hh_geog, key))][math.floor(
                                time_to_use / 24)] += 1

                        for key, value in self.rep.active_paper_totals.items():
                            value[str(getattr(hh_geog, key))] += 1

                    if oo.record_responded:
                        self.rep.output_data['Responded'].append(
                            oo.generic_output(self.rep.reps, self.district,
                                              hh_geog.la, hh_geog.lsoa,
                                              hh_action.digital, hh_type,
                                              self.rep.total_hh, time_to_use))
                else:
                    # create a household instance passing initial state
                    self.households.append(
                        household.Household(self.rep, self.env, self,
                                            self.rep.total_hh, hh_type,
                                            hh_input_data, hh_action,
                                            hh_geog.la, hh_geog.lsoa))

                # if self.rep.reps == 1:
                if self.rep.reps > 0 and oo.record_hh_record:
                    self.rep.output_data['hh_record'].append(
                        oo.hh_record(self.rep.reps, self.district, hh_geog.la,
                                     hh_geog.lsoa, hh_type, hh_action.type,
                                     hh_action.digital,
                                     hh_input_data['paper_allowed'],
                                     hh_action.time))

                if hh_action.type not in ['do_nothing', 'help'
                                          ] and oo.record_passive_summary:

                    for key, value in self.rep.passive_summary.items():
                        value[str(getattr(hh_geog, key))][math.floor(
                            time_to_use / 24)] += 1

                    for key, value in self.rep.passive_totals.items():
                        value[str(getattr(hh_geog, key))] += 1

                self.rep.total_hh += 1
Example #15
0
    def receive_reminder(self, reminder_type):
        # a reminder has been received. This determines the outcome fo that reminder and if it was worthwhile.

        if oo.record_reminder_received:
            self.rep.output_data[reminder_type + '_received'].append(oo.reminder_received(self.rep.reps,
                                                                                          self.district.district,
                                                                                          self.la,
                                                                                          self.lsoa,
                                                                                          self.digital,
                                                                                          self.hh_type,
                                                                                          self.hh_id,
                                                                                          self.env.now,
                                                                                          reminder_type))
        # set resp according to type of hh and reminder
        if not self.resp_planned and reminder_type == 'pq' and self.engaged:
            self.paper_allowed = True
            self.resp_level = 100  # so this assumes if you provide paper to those engaged they will respond

        elif not self.resp_planned:
            behaviour = self.default_behaviour()
            # and get relevant figures
            try:
                response_data = self.input_data["behaviours"][reminder_type][behaviour]
            except:
                pass
            self.resp_level = response_data["response"]
            if self.rep.total_ad_instances > 0:
                self.help_level = response_data["help"]
            else:
                self.help_level = 0

        # recorded if wasted, unnecessary or successful
        if self.responded:

            if oo.record_reminder_wasted:
                self.rep.output_data[reminder_type + '_wasted'].append(oo.reminder_wasted(self.rep.reps,
                                                                                          self.district.district,
                                                                                          self.la,
                                                                                          self.lsoa,
                                                                                          self.digital,
                                                                                          self.hh_type,
                                                                                          self.hh_id,
                                                                                          self.env.now,
                                                                                          reminder_type))
        elif self.resp_planned:

            if oo.record_reminder_unnecessary:
                self.rep.output_data[reminder_type + '_unnecessary'].append(oo.reminder_unnecessary(self.rep.reps,
                                                                                                    self.district.district,
                                                                                                    self.la,
                                                                                                    self.lsoa,
                                                                                                    self.digital,
                                                                                                    self.hh_type,
                                                                                                    self.hh_id,
                                                                                                    self.env.now,
                                                                                                    reminder_type))
        # now move on to the relevant action based on extracted values
        reminder_test = self.rnd.uniform(0, 100)

        if not self.resp_planned and reminder_test <= self.resp_level:
            if oo.record_reminder_success:
                self.rep.output_data[reminder_type + '_success'].append(oo.reminder_success(self.rep.reps,
                                                                                            self.district.district,
                                                                                            self.la,
                                                                                            self.lsoa,
                                                                                            self.digital,
                                                                                            self.hh_type,
                                                                                            self.hh_id,
                                                                                            self.env.now,
                                                                                            reminder_type))
            # change to a start delayed at appropriate time depending on day....
            delay = h.get_time_of_return(self.env.now, self.rep)
            # yield self.env.process(self.household_returns(self.calc_delay()))

            ##########
            # if this is a pq, but a digital household, calculate if the household retunrs via paper or digital?
            # Or assume use preferred method for now?
            # could use paper first paper prop to set this? so set digital to true or false...
            ##########

            start_delayed(self.env, self.household_returns(self.calc_delay()), delay)
            yield self.env.timeout(0)

        elif not self.resp_planned and (self.resp_level < reminder_test <= self.resp_level + self.help_level):
            # call for help...needs to be based on appropriate distribution...not a hardcoded uniform function!
            # also may not do this if intend to respond?
            yield self.env.timeout(self.rnd.uniform(0, 8))

            if oo.record_do_nothing:
                self.output_data[reminder_type + '_contact'].append(oo.generic_output(self.rep.reps,
                                                                                     self.district.district,
                                                                                     self.la,
                                                                                     self.lsoa,
                                                                                     self.digital,
                                                                                     self.hh_type,
                                                                                     self.hh_id,
                                                                                     self.env.now))

            yield self.env.process(self.contact())
        else:
            # nowt
            if oo.record_do_nothing:
                self.output_data[reminder_type + '_failed'].append(oo.generic_output(self.rep.reps,
                                                                                     self.district.district,
                                                                                     self.la,
                                                                                     self.lsoa,
                                                                                     self.digital,
                                                                                     self.hh_type,
                                                                                     self.hh_id,
                                                                                     self.env.now))

        yield self.env.timeout(0)