<commit_before>COMPOSITE_INDICATORS = dict(
    # Child Health
    under5_fever_rdt_proportion=dict(
        description="Proportion of children aged 6-59 months with "
                    "uncomplicated fever who received RDT test",
        title="% Under-5s w/ uncomplicated fever who received RDT test",
        numerator_slug="under5_fever_rdt",
        denominator_slug="under5_fever"
    ),
    under5_fever_rdt_positive_proportion=dict(
        description="Proportion of children aged 6-59 months with uncomplicated"
                    " fever who received RDT test and were RDT positive",
        title="% Under-5s with uncomplicated fever who received RDT test and were RDT positive",
        numerator_slug="under5_fever_rdt_positive",
        denominator_slug="under5_fever_rdt"
    ),
    under5_fever_rdt_positive_medicated_proportion=dict(
        description="Proportion of children aged 6-59 months with positive RDT"
                    " result who received antimalarial/ADT medication",
        title="% Under-5s w/ Positive RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_positive_medicated",
        denominator_slug="under5_fever_rdt_positive"
    ),
    under5_fever_rdt_not_received_proportion=dict(
        description="Proportion of children aged 6-59 months with uncomplicated"
                    " fever who did NOT receive RDT test due to 'RDT not available' with CHW",
        title="% Under-5s w/ RDT Not Available",
        numerator_slug="under5_fever_rdt_not_received",
        denominator_slug="under5_fever"
    ),
    under5_diarrhea_ors_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ORS",
        title="% Under-5s with uncomplicated diarrhea who received ORS",
        numerator_slug="under5_diarrhea_ors",
        denominator_slug="under5_diarrhea"
    ),
    under5_diarrhea_zinc_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ZINC",
        title="% Under-5s with uncomplicated diarrhea who received ZINC",
        numerator_slug="under5_diarrhea_zinc",
        denominator_slug="under5_diarrhea"
    ),
    under5_complicated_fever_facility_followup_proportion=dict(
        description="Proportion of children who attended follow-up at facility after being referred"\
                    " for complicated fever",
        title="% Under-5 attending follow-up at facility after complicated fever referral",
        numerator_slug="under5_complicated_fever_facility_followup",
        denominator_slug="under5_complicated_fever_case",
    ),
    under5_complicated_fever_referred_proportion=dict(
        description="Proportion of Under-5s with complicated fever who were referred to clinic or hospital",
        title="% of Under-5s with complicated fever referred to clinic/hospital",
        numerator_slug="under5_complicated_fever_referred",
        denominator_slug="under5_complicated_fever",
    ),
    under1_check_ups_proportion=dict(
        description="Proportion of children Under-1 receiving on-time scheduled check-ups during the time period",
        title="% Under-1 receiving check-ups",
        numerator_slug="under1_visits_6weeks",
        denominator_slug="under1_cases_6weeks",
    ),
    under1_immunized_proportion=dict(
        description="Proportion of children under-1 reported as up-to-date on immunizations at " \
                    "last visit during the time period",
        title="% of Under-1 with up-to-date immunization",
        numerator_slug="under1_immunization_up_to_date",
        denominator_slug="under1_visits",
    ),
    under5_fever_rdt_negative_medicated_proportion=dict(
        description="Proportion of children aged 6-59 months with negative RDT"
                    " result who received antimalarial/ADT medication",
        title="% Under-5s w/ Negative RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_negative_medicated",
        denominator_slug="under5_fever_rdt_negative"
    ),

    # Child Nutrition
    moderate_muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with moderate wasting (MUAC 115<125) "\
                    "at last MUAC reading this time period",
        title="% 6-59 month Children with moderate MUAC (115<125)",
        numerator_slug="child_moderate_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    severe_muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with severe wasting (MUAC <115) "\
                    "at last MUAC reading this time period",
        title="% 6-59 month Children with severe MUAC < 115",
        numerator_slug="child_severe_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with moderate or severe wasting (MUAC < 125) "\
                    "at last MUAC reading this time period",
        title="% Under-5s with MUAC < 125",
        numerator_slug="child_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    muac_routine_proportion=dict(
        description="Proportion of children aged 6-59 months receiving on-time routine (every 30 days) MUAC "\
                    "readings during the time period",
        title="% Under-5s receiving on-time MUAC (30 days)",
        numerator_slug="child_muac_routine",
        denominator_slug="num_children_6to59months"
    ),
    under6month_exclusive_breastfeeding_proportion=dict(
        description="Proportion of children under 6 months reported as exclusively breast-fed at last " \
                    "visit during the time period",
        title="% Under-6-Months reported as exclusively breast-fed",
        numerator_slug="under6month_exclusive_breastfeeding",
        denominator_slug="under6month_visits",
    ),
    low_birth_weight_proportion=dict(
        description="Proportion of low birth weight (<2.5 kg) babies born during the time period",
        title="% low birth weight (<2.5 kg) babies born during the time period",
        numerator_slug="low_birth_weight",
        denominator_slug="birth_weight_registration",
    ),

    # CHW Visits
    households_routine_visit_past90days=dict(
        description="Proportion of Households receiving on-time routine visit within last 90 DAYS",
        title="% of HHs receiving visit in last 90 DAYS",
        numerator_slug="household_visits_90days",
        denominator_slug="household_cases_90days"
    ),
    households_routine_visit_past30days=dict(
        description="Proportion of Households receiving on-time routine visit within last 30 DAYS",
        title="% of HHs receiving visit in last 30 DAYS",
        numerator_slug="household_visits_30days",
        denominator_slug="household_cases_30days"
    ),
    under5_routine_visit_past30days=dict(
        description="Proportion of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        title="% of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="under5_visits_30days",
        denominator_slug="under5_cases_30days"
    ),
    pregnant_routine_visit_past30days=dict(
        description="Proportion of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        title="% of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="pregnancy_visits_30days",
        denominator_slug="pregnancy_cases_30days"
    ),
    neonate_routine_visit_past7days=dict(
        description="Proportion of Neonates (less than 29 days old) receiving "
                    "on-time routine visit in the past 7 days "
                    "(from end of reporting period)",
        title="% of Neonates (less than 29 days old) receiving on-time routine"
              " visit in the past 7 days (from end of reporting period)",
        numerator_slug="neonate_visits_7days",
        denominator_slug="neonate_cases_7days"
    ),
    newborn_7day_visit_proportion=dict(
        description=" Proportion of children (LESS THAN 8 DAYS OLD) receiving first CHW check-up" \
		    "within 7 days of birth during the time period",
        title="% Newborns checked within 7 days of birth",
        numerator_slug="newborn_visits",
        denominator_slug="num_newborns"
    ),
    pregnancy_visit_danger_sign_referral_proportion=dict(
        description="Proportion of Pregnant Women Referred for Danger Signs",
        title="% Pregnant Women Referred for Danger Signs",
        numerator_slug="pregnancy_visit_danger_sign_referral",
        denominator_slug="pregnancy_visit_danger_sign",
    ),

    # Followups
    urgent_referrals_proportion=dict(
        description="Proportion of urgent referrals (codes A, E, B) or treatment receiving CHW " \
                    "follow-up within 2 days of referral / treatment during the time period",
        title="% Referred / Treated receiving on-time follow-up (within 2 days)",
        numerator_slug="urgent_referral_followups",
        denominator_slug="num_urgent_referrals"
    ),
    late_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving LATE follow-up (within 3-7 days)",
        title="% Referred / Treated receiving LATE follow-up (within 3-7 days)",
        numerator_slug="num_late_followups",
        denominator_slug="num_urgent_referrals",
    ),
    no_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving NO follow-up",
        title="% Referred / Treated receiving NO follow-up",
        numerator_slug="num_none_followups",
        denominator_slug="num_urgent_referrals",
    ),

    # Maternal Health
    family_planning_proportion=dict(
        description="Proportion of women 15-49 years old reporting use of " \
                    "modern family planning method at last visit this time period",
        title="% women 15-49 years old reporting use of modern family planning method",
        numerator_slug="household_num_fp",
        denominator_slug="household_num_ec"
    ),
    anc4_proportion=dict(
        description="Proportion of Pregnant women reporting at least four (4) Antenatal Care " \
                    "visit by 8 months of gestation this time period",
        title="% of Pregnant receiving 4 ANC visits to facility by 8 months gestation",
        numerator_slug="edd_soon_anc4",
        denominator_slug="edd_soon_visit"
    ),
    no_anc_proportion=dict(
        description="Proportion of Pregnant women reporting no Antenatal Care visit by " \
                    "4 months of gestation this time period",
        title="% Pregnant women reporting no Antenatal Care visit by 4 months of gestation",
        numerator_slug="no_anc",
        denominator_slug="anc_visit_120"
    ),
    facility_births_proportion=dict(
        description="Proportion of Births delivered in a Health Facility during the time period",
        title="% Births delivered in Health Facility",
        numerator_slug="num_births_registered_in_facility",
        denominator_slug="num_births_registered"
    ),
    pregnant_routine_checkup_proportion_6weeks=dict(
        description="Proportion of Pregnant women receiving on-time routine check-up (every 6 weeks)",
        title="% Pregnant receiving CHW visit in last 6 weeks",
        numerator_slug="pregnancy_visits_6weeks",
        denominator_slug="pregnancy_cases_6weeks",
    ),

    # Over5 Health
    over5_positive_rdt_medicated_proportion=dict(
        description="Proportion of Over-5s with positive RDT result who received antimalarial/ADT medication",
        title="% of Over-5s with positive RDT result who received antimalarial/ADT medication",
        numerator_slug="over5_positive_rdt_medicated",
        denominator_slug="over5_positive_rdt",
    ),

    #Functioning Bednet
    functioning_bednet_proportion=dict(
        description="Proportion of households ASSESSED with at least one functioning bednet"\
                    "per sleeping site during the time period",
        title="% of households ASSESSED with at least one functioning bednet per sleeping site",
        numerator_slug="household_num_func_bednets",
        denominator_slug="household_num_bednets",
    ),

    #Handwashing
    latrine_with_handwashing_proportion=dict(
        description="Proportion of households ASSESSED with handwashing station within 10m"\
                    " of the latrine during the time period",
        title="% of households ASSESSED with handwashing station within 10m of the latrine",
        numerator_slug="num_handwashing_latrine",
        denominator_slug="num_handwashing",
    ),
)
<commit_msg>fix handwashing indicator<commit_after>COMPOSITE_INDICATORS = dict(
    # Child Health
    under5_fever_rdt_proportion=dict(
        description="Proportion of children aged 6-59 months with "
                    "uncomplicated fever who received RDT test",
        title="% Under-5s w/ uncomplicated fever who received RDT test",
        numerator_slug="under5_fever_rdt",
        denominator_slug="under5_fever"
    ),
    under5_fever_rdt_positive_proportion=dict(
        description="Proportion of children aged 6-59 months with uncomplicated"
                    " fever who received RDT test and were RDT positive",
        title="% Under-5s with uncomplicated fever who received RDT test and were RDT positive",
        numerator_slug="under5_fever_rdt_positive",
        denominator_slug="under5_fever_rdt"
    ),
    under5_fever_rdt_positive_medicated_proportion=dict(
        description="Proportion of children aged 6-59 months with positive RDT"
                    " result who received antimalarial/ADT medication",
        title="% Under-5s w/ Positive RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_positive_medicated",
        denominator_slug="under5_fever_rdt_positive"
    ),
    under5_fever_rdt_not_received_proportion=dict(
        description="Proportion of children aged 6-59 months with uncomplicated"
                    " fever who did NOT receive RDT test due to 'RDT not available' with CHW",
        title="% Under-5s w/ RDT Not Available",
        numerator_slug="under5_fever_rdt_not_received",
        denominator_slug="under5_fever"
    ),
    under5_diarrhea_ors_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ORS",
        title="% Under-5s with uncomplicated diarrhea who received ORS",
        numerator_slug="under5_diarrhea_ors",
        denominator_slug="under5_diarrhea"
    ),
    under5_diarrhea_zinc_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ZINC",
        title="% Under-5s with uncomplicated diarrhea who received ZINC",
        numerator_slug="under5_diarrhea_zinc",
        denominator_slug="under5_diarrhea"
    ),
    under5_complicated_fever_facility_followup_proportion=dict(
        description="Proportion of children who attended follow-up at facility after being referred"\
                    " for complicated fever",
        title="% Under-5 attending follow-up at facility after complicated fever referral",
        numerator_slug="under5_complicated_fever_facility_followup",
        denominator_slug="under5_complicated_fever_case",
    ),
    under5_complicated_fever_referred_proportion=dict(
        description="Proportion of Under-5s with complicated fever who were referred to clinic or hospital",
        title="% of Under-5s with complicated fever referred to clinic/hospital",
        numerator_slug="under5_complicated_fever_referred",
        denominator_slug="under5_complicated_fever",
    ),
    under1_check_ups_proportion=dict(
        description="Proportion of children Under-1 receiving on-time scheduled check-ups during the time period",
        title="% Under-1 receiving check-ups",
        numerator_slug="under1_visits_6weeks",
        denominator_slug="under1_cases_6weeks",
    ),
    under1_immunized_proportion=dict(
        description="Proportion of children under-1 reported as up-to-date on immunizations at " \
                    "last visit during the time period",
        title="% of Under-1 with up-to-date immunization",
        numerator_slug="under1_immunization_up_to_date",
        denominator_slug="under1_visits",
    ),
    under5_fever_rdt_negative_medicated_proportion=dict(
        description="Proportion of children aged 6-59 months with negative RDT"
                    " result who received antimalarial/ADT medication",
        title="% Under-5s w/ Negative RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_negative_medicated",
        denominator_slug="under5_fever_rdt_negative"
    ),

    # Child Nutrition
    moderate_muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with moderate wasting (MUAC 115<125) "\
                    "at last MUAC reading this time period",
        title="% 6-59 month Children with moderate MUAC (115<125)",
        numerator_slug="child_moderate_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    severe_muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with severe wasting (MUAC <115) "\
                    "at last MUAC reading this time period",
        title="% 6-59 month Children with severe MUAC < 115",
        numerator_slug="child_severe_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with moderate or severe wasting (MUAC < 125) "\
                    "at last MUAC reading this time period",
        title="% Under-5s with MUAC < 125",
        numerator_slug="child_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    muac_routine_proportion=dict(
        description="Proportion of children aged 6-59 months receiving on-time routine (every 30 days) MUAC "\
                    "readings during the time period",
        title="% Under-5s receiving on-time MUAC (30 days)",
        numerator_slug="child_muac_routine",
        denominator_slug="num_children_6to59months"
    ),
    under6month_exclusive_breastfeeding_proportion=dict(
        description="Proportion of children under 6 months reported as exclusively breast-fed at last " \
                    "visit during the time period",
        title="% Under-6-Months reported as exclusively breast-fed",
        numerator_slug="under6month_exclusive_breastfeeding",
        denominator_slug="under6month_visits",
    ),
    low_birth_weight_proportion=dict(
        description="Proportion of low birth weight (<2.5 kg) babies born during the time period",
        title="% low birth weight (<2.5 kg) babies born during the time period",
        numerator_slug="low_birth_weight",
        denominator_slug="birth_weight_registration",
    ),

    # CHW Visits
    households_routine_visit_past90days=dict(
        description="Proportion of Households receiving on-time routine visit within last 90 DAYS",
        title="% of HHs receiving visit in last 90 DAYS",
        numerator_slug="household_visits_90days",
        denominator_slug="household_cases_90days"
    ),
    households_routine_visit_past30days=dict(
        description="Proportion of Households receiving on-time routine visit within last 30 DAYS",
        title="% of HHs receiving visit in last 30 DAYS",
        numerator_slug="household_visits_30days",
        denominator_slug="household_cases_30days"
    ),
    under5_routine_visit_past30days=dict(
        description="Proportion of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        title="% of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="under5_visits_30days",
        denominator_slug="under5_cases_30days"
    ),
    pregnant_routine_visit_past30days=dict(
        description="Proportion of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        title="% of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="pregnancy_visits_30days",
        denominator_slug="pregnancy_cases_30days"
    ),
    neonate_routine_visit_past7days=dict(
        description="Proportion of Neonates (less than 29 days old) receiving "
                    "on-time routine visit in the past 7 days "
                    "(from end of reporting period)",
        title="% of Neonates (less than 29 days old) receiving on-time routine"
              " visit in the past 7 days (from end of reporting period)",
        numerator_slug="neonate_visits_7days",
        denominator_slug="neonate_cases_7days"
    ),
    newborn_7day_visit_proportion=dict(
        description=" Proportion of children (LESS THAN 8 DAYS OLD) receiving first CHW check-up" \
		    "within 7 days of birth during the time period",
        title="% Newborns checked within 7 days of birth",
        numerator_slug="newborn_visits",
        denominator_slug="num_newborns"
    ),
    pregnancy_visit_danger_sign_referral_proportion=dict(
        description="Proportion of Pregnant Women Referred for Danger Signs",
        title="% Pregnant Women Referred for Danger Signs",
        numerator_slug="pregnancy_visit_danger_sign_referral",
        denominator_slug="pregnancy_visit_danger_sign",
    ),

    # Followups
    urgent_referrals_proportion=dict(
        description="Proportion of urgent referrals (codes A, E, B) or treatment receiving CHW " \
                    "follow-up within 2 days of referral / treatment during the time period",
        title="% Referred / Treated receiving on-time follow-up (within 2 days)",
        numerator_slug="urgent_referral_followups",
        denominator_slug="num_urgent_referrals"
    ),
    late_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving LATE follow-up (within 3-7 days)",
        title="% Referred / Treated receiving LATE follow-up (within 3-7 days)",
        numerator_slug="num_late_followups",
        denominator_slug="num_urgent_referrals",
    ),
    no_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving NO follow-up",
        title="% Referred / Treated receiving NO follow-up",
        numerator_slug="num_none_followups",
        denominator_slug="num_urgent_referrals",
    ),

    # Maternal Health
    family_planning_proportion=dict(
        description="Proportion of women 15-49 years old reporting use of " \
                    "modern family planning method at last visit this time period",
        title="% women 15-49 years old reporting use of modern family planning method",
        numerator_slug="household_num_fp",
        denominator_slug="household_num_ec"
    ),
    anc4_proportion=dict(
        description="Proportion of Pregnant women reporting at least four (4) Antenatal Care " \
                    "visit by 8 months of gestation this time period",
        title="% of Pregnant receiving 4 ANC visits to facility by 8 months gestation",
        numerator_slug="edd_soon_anc4",
        denominator_slug="edd_soon_visit"
    ),
    no_anc_proportion=dict(
        description="Proportion of Pregnant women reporting no Antenatal Care visit by " \
                    "4 months of gestation this time period",
        title="% Pregnant women reporting no Antenatal Care visit by 4 months of gestation",
        numerator_slug="no_anc",
        denominator_slug="anc_visit_120"
    ),
    facility_births_proportion=dict(
        description="Proportion of Births delivered in a Health Facility during the time period",
        title="% Births delivered in Health Facility",
        numerator_slug="num_births_registered_in_facility",
        denominator_slug="num_births_registered"
    ),
    pregnant_routine_checkup_proportion_6weeks=dict(
        description="Proportion of Pregnant women receiving on-time routine check-up (every 6 weeks)",
        title="% Pregnant receiving CHW visit in last 6 weeks",
        numerator_slug="pregnancy_visits_6weeks",
        denominator_slug="pregnancy_cases_6weeks",
    ),

    # Over5 Health
    over5_positive_rdt_medicated_proportion=dict(
        description="Proportion of Over-5s with positive RDT result who received antimalarial/ADT medication",
        title="% of Over-5s with positive RDT result who received antimalarial/ADT medication",
        numerator_slug="over5_positive_rdt_medicated",
        denominator_slug="over5_positive_rdt",
    ),

    #Functioning Bednet
    functioning_bednet_proportion=dict(
        description="Proportion of households ASSESSED with at least one functioning bednet"\
                    "per sleeping site during the time period",
        title="% of households ASSESSED with at least one functioning bednet per sleeping site",
        numerator_slug="household_num_func_bednets",
        denominator_slug="household_num_bednets",
    ),

    #Handwashing
    handwashing_near_latrine_proportion=dict(
        description="Proportion of households ASSESSED with handwashing station within 10m"\
                    " of the latrine during the time period",
        title="% of households ASSESSED with handwashing station within 10m of the latrine",
        numerator_slug="num_handwashing_latrine",
        denominator_slug="num_handwashing",
    ),
)
<|endoftext|>


<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack, LLC
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from nose.plugins.attrib import attr

from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.tests.compute import base
from tempest import whitebox

@attr(type='whitebox')
class ImagesWhiteboxTest(whitebox.ComputeWhiteboxTest, base.BaseComputeTest):

    @classmethod
    def setUpClass(cls):
        super(ImagesWhiteboxTest, cls).setUpClass()
        cls.client = cls.images_client
        cls.connection, cls.meta = cls.get_db_handle_and_meta()
        cls.shared_server = cls.create_server()
        cls.image_ids = []

    @classmethod
    def tearDownClass(cls):
        """Terminate test instances created after a test is executed."""

        for server in cls.servers:
            cls.update_state(server['id'], "active", None)
            resp, body = cls.servers_client.delete_server(server['id'])
            if resp['status'] == '204':
                cls.servers.remove(server)
                cls.servers_client.wait_for_server_termination(server['id'])

        for image_id in cls.image_ids:
            cls.client.delete_image(image_id)
            cls.image_ids.remove(image_id)

    @classmethod
    def update_state(self, server_id, vm_state, task_state, deleted=False):
        """Update states of an instance in database for validation."""
        if not task_state:
            task_state = "NULL"

        instances = self.meta.tables['instances']
        stmt = instances.update().where(instances.c.uuid == server_id).values(
            deleted=deleted,
            vm_state=vm_state,
            task_state=task_state)

        self.connection.execute(stmt, autocommit=True)

    def _test_create_image_409_base(self, vm_state, task_state, deleted=False):
        """Base method for create image tests based on vm and task states."""
        try:
            self.update_state(self.shared_server['id'], vm_state,
                              task_state, deleted)

            image_name = rand_name('snap-')
            self.assertRaises(exceptions.Duplicate,
                              self.client.create_image,
                              self.shared_server['id'], image_name)
        except Exception:
            self.fail("Should not allow create image when vm_state=%s and "
                      "task_state=%s" % (vm_state, task_state))
        finally:
            self.update_state(self.shared_server['id'], 'active', None)

    def test_create_image_when_vm_eq_building_task_eq_scheduling(self):
        # 409 error when instance states are building,scheduling
        self._test_create_image_409_base("building", "scheduling")

    def test_create_image_when_vm_eq_building_task_eq_networking(self):
        # 409 error when instance states are building,networking
        self._test_create_image_409_base("building", "networking")

    def test_create_image_when_vm_eq_building_task_eq_bdm(self):
        # 409 error when instance states are building,block_device_mapping
        self._test_create_image_409_base("building", "block_device_mapping")

    def test_create_image_when_vm_eq_building_task_eq_spawning(self):
        # 409 error when instance states are building,spawning
        self._test_create_image_409_base("building", "spawning")

    def test_create_image_when_vm_eq_active_task_eq_image_backup(self):
        # 409 error when instance states are active,image_backup
        self._test_create_image_409_base("active", "image_backup")

    def test_create_image_when_vm_eq_resized_task_eq_resize_prep(self):
        # 409 error when instance states are resized,resize_prep
        self._test_create_image_409_base("resized", "resize_prep")

    def test_create_image_when_vm_eq_resized_task_eq_resize_migrating(self):
        # 409 error when instance states are resized,resize_migrating
        self._test_create_image_409_base("resized", "resize_migrating")

    def test_create_image_when_vm_eq_resized_task_eq_resize_migrated(self):
        # 409 error when instance states are resized,resize_migrated
        self._test_create_image_409_base("resized", "resize_migrated")

    def test_create_image_when_vm_eq_resized_task_eq_resize_finish(self):
        # 409 error when instance states are resized,resize_finish
        self._test_create_image_409_base("resized", "resize_finish")

    def test_create_image_when_vm_eq_resized_task_eq_resize_reverting(self):
        # 409 error when instance states are resized,resize_reverting
        self._test_create_image_409_base("resized", "resize_reverting")

    def test_create_image_when_vm_eq_resized_task_eq_resize_confirming(self):
        # 409 error when instance states are resized,resize_confirming
        self._test_create_image_409_base("resized", "resize_confirming")

    def test_create_image_when_vm_eq_active_task_eq_resize_verify(self):
        # 409 error when instance states are active,resize_verify
        self._test_create_image_409_base("active", "resize_verify")

    def test_create_image_when_vm_eq_active_task_eq_updating_password(self):
        # 409 error when instance states are active,updating_password
        self._test_create_image_409_base("active", "updating_password")

    def test_create_image_when_vm_eq_active_task_eq_rebuilding(self):
        # 409 error when instance states are active,rebuilding
        self._test_create_image_409_base("active", "rebuilding")

    def test_create_image_when_vm_eq_active_task_eq_rebooting(self):
        # 409 error when instance states are active,rebooting
        self._test_create_image_409_base("active", "rebooting")

    def test_create_image_when_vm_eq_building_task_eq_deleting(self):
        # 409 error when instance states are building,deleting
        self._test_create_image_409_base("building", "deleting")

    def test_create_image_when_vm_eq_active_task_eq_deleting(self):
        # 409 error when instance states are active,deleting
        self._test_create_image_409_base("active", "deleting")

    def test_create_image_when_vm_eq_error_task_eq_building(self):
        # 409 error when instance states are error,building
        self._test_create_image_409_base("error", "building")

    def test_create_image_when_vm_eq_error_task_eq_none(self):
        # 409 error when instance states are error,None
        self._test_create_image_409_base("error", None)

    def test_create_image_when_vm_eq_deleted_task_eq_none(self):
        # 409 error when instance states are deleted,None
        self._test_create_image_409_base("deleted", None)

    def test_create_image_when_vm_eq_resized_task_eq_none(self):
        # 409 error when instance states are resized,None
        self._test_create_image_409_base("resized", None)

    def test_create_image_when_vm_eq_error_task_eq_resize_prep(self):
        # 409 error when instance states are error,resize_prep
        self._test_create_image_409_base("error", "resize_prep")
<commit_msg>Fixes whitebox testing for deleted type change<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack, LLC
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from nose.plugins.attrib import attr

from tempest.common.utils.data_utils import rand_name
from tempest import exceptions
from tempest.tests.compute import base
from tempest import whitebox

@attr(type='whitebox')
class ImagesWhiteboxTest(whitebox.ComputeWhiteboxTest, base.BaseComputeTest):

    @classmethod
    def setUpClass(cls):
        super(ImagesWhiteboxTest, cls).setUpClass()
        cls.client = cls.images_client
        cls.connection, cls.meta = cls.get_db_handle_and_meta()
        cls.shared_server = cls.create_server()
        cls.image_ids = []

    @classmethod
    def tearDownClass(cls):
        """Terminate test instances created after a test is executed."""

        for server in cls.servers:
            cls.update_state(server['id'], "active", None)
            resp, body = cls.servers_client.delete_server(server['id'])
            if resp['status'] == '204':
                cls.servers.remove(server)
                cls.servers_client.wait_for_server_termination(server['id'])

        for image_id in cls.image_ids:
            cls.client.delete_image(image_id)
            cls.image_ids.remove(image_id)

    @classmethod
    def update_state(self, server_id, vm_state, task_state, deleted=0):
        """Update states of an instance in database for validation."""
        if not task_state:
            task_state = "NULL"

        instances = self.meta.tables['instances']
        stmt = instances.update().where(instances.c.uuid == server_id).values(
            deleted=deleted,
            vm_state=vm_state,
            task_state=task_state)

        self.connection.execute(stmt, autocommit=True)

    def _test_create_image_409_base(self, vm_state, task_state, deleted=0):
        """Base method for create image tests based on vm and task states."""
        try:
            self.update_state(self.shared_server['id'], vm_state,
                              task_state, deleted)

            image_name = rand_name('snap-')
            self.assertRaises(exceptions.Duplicate,
                              self.client.create_image,
                              self.shared_server['id'], image_name)
        except Exception:
            self.fail("Should not allow create image when vm_state=%s and "
                      "task_state=%s" % (vm_state, task_state))
        finally:
            self.update_state(self.shared_server['id'], 'active', None)

    def test_create_image_when_vm_eq_building_task_eq_scheduling(self):
        # 409 error when instance states are building,scheduling
        self._test_create_image_409_base("building", "scheduling")

    def test_create_image_when_vm_eq_building_task_eq_networking(self):
        # 409 error when instance states are building,networking
        self._test_create_image_409_base("building", "networking")

    def test_create_image_when_vm_eq_building_task_eq_bdm(self):
        # 409 error when instance states are building,block_device_mapping
        self._test_create_image_409_base("building", "block_device_mapping")

    def test_create_image_when_vm_eq_building_task_eq_spawning(self):
        # 409 error when instance states are building,spawning
        self._test_create_image_409_base("building", "spawning")

    def test_create_image_when_vm_eq_active_task_eq_image_backup(self):
        # 409 error when instance states are active,image_backup
        self._test_create_image_409_base("active", "image_backup")

    def test_create_image_when_vm_eq_resized_task_eq_resize_prep(self):
        # 409 error when instance states are resized,resize_prep
        self._test_create_image_409_base("resized", "resize_prep")

    def test_create_image_when_vm_eq_resized_task_eq_resize_migrating(self):
        # 409 error when instance states are resized,resize_migrating
        self._test_create_image_409_base("resized", "resize_migrating")

    def test_create_image_when_vm_eq_resized_task_eq_resize_migrated(self):
        # 409 error when instance states are resized,resize_migrated
        self._test_create_image_409_base("resized", "resize_migrated")

    def test_create_image_when_vm_eq_resized_task_eq_resize_finish(self):
        # 409 error when instance states are resized,resize_finish
        self._test_create_image_409_base("resized", "resize_finish")

    def test_create_image_when_vm_eq_resized_task_eq_resize_reverting(self):
        # 409 error when instance states are resized,resize_reverting
        self._test_create_image_409_base("resized", "resize_reverting")

    def test_create_image_when_vm_eq_resized_task_eq_resize_confirming(self):
        # 409 error when instance states are resized,resize_confirming
        self._test_create_image_409_base("resized", "resize_confirming")

    def test_create_image_when_vm_eq_active_task_eq_resize_verify(self):
        # 409 error when instance states are active,resize_verify
        self._test_create_image_409_base("active", "resize_verify")

    def test_create_image_when_vm_eq_active_task_eq_updating_password(self):
        # 409 error when instance states are active,updating_password
        self._test_create_image_409_base("active", "updating_password")

    def test_create_image_when_vm_eq_active_task_eq_rebuilding(self):
        # 409 error when instance states are active,rebuilding
        self._test_create_image_409_base("active", "rebuilding")

    def test_create_image_when_vm_eq_active_task_eq_rebooting(self):
        # 409 error when instance states are active,rebooting
        self._test_create_image_409_base("active", "rebooting")

    def test_create_image_when_vm_eq_building_task_eq_deleting(self):
        # 409 error when instance states are building,deleting
        self._test_create_image_409_base("building", "deleting")

    def test_create_image_when_vm_eq_active_task_eq_deleting(self):
        # 409 error when instance states are active,deleting
        self._test_create_image_409_base("active", "deleting")

    def test_create_image_when_vm_eq_error_task_eq_building(self):
        # 409 error when instance states are error,building
        self._test_create_image_409_base("error", "building")

    def test_create_image_when_vm_eq_error_task_eq_none(self):
        # 409 error when instance states are error,None
        self._test_create_image_409_base("error", None)

    def test_create_image_when_vm_eq_deleted_task_eq_none(self):
        # 409 error when instance states are deleted,None
        self._test_create_image_409_base("deleted", None)

    def test_create_image_when_vm_eq_resized_task_eq_none(self):
        # 409 error when instance states are resized,None
        self._test_create_image_409_base("resized", None)

    def test_create_image_when_vm_eq_error_task_eq_resize_prep(self):
        # 409 error when instance states are error,resize_prep
        self._test_create_image_409_base("error", "resize_prep")
<|endoftext|>


<commit_before>COMPOSITE_INDICATORS = dict(
    # Child Health
    under5_fever_rdt_proportion=dict(
        description="Proportion of Under-5s with uncomplicated fever who received RDT test",
        title="% Under-5s w/ uncomplicated fever who received RDT test",
        numerator_slug="under5_fever_rdt",
        denominator_slug="under5_fever"
    ),
    under5_fever_rdt_positive_proportion=dict(
        description="Proportion of Under-5s with uncomplicated fever who received RDT test and were RDT positive",
        title="% Under-5s with uncomplicated fever who received RDT test and were RDT positive",
        numerator_slug="under5_fever_rdt_positive",
        denominator_slug="under5_fever_rdt"
    ),
    under5_fever_rdt_positive_medicated_proportion=dict(
        description="Proportion of Under-5s with positive RDT result who received antimalarial/ADT medication",
        title="% Under-5s w/ Positive RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_positive_medicated",
        denominator_slug="under5_fever_rdt_positive"
    ),
    under5_fever_rdt_not_received_proportion=dict(
        description="Proportion of Under-5s with uncomplicated fever who did NOT receive RDT "
                    "test due to 'RDT not available' with CHW",
        title="% Under-5s w/ RDT Not Available",
        numerator_slug="under5_fever_rdt_not_received",
        denominator_slug="under5_fever"
    ),
    under5_diarrhea_ors_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ORS",
        title="% Under-5s with uncomplicated diarrhea who received ORS",
        numerator_slug="under5_diarrhea_ors",
        denominator_slug="under5_diarrhea"
    ),
    under5_diarrhea_zinc_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ZINC",
        title="% Under-5s with uncomplicated diarrhea who received ZINC",
        numerator_slug="under5_diarrhea_zinc",
        denominator_slug="under5_diarrhea"
    ),
    under5_complicated_fever_facility_followup_proportion=dict(
        description="Proportion of children who attended follow-up at facility after being referred"\
                    " for complicated fever",
        title="% Under-5 attending follow-up at facility after complicated fever referral",
        numerator_slug="under5_complicated_fever_facility_followup",
        denominator_slug="under5_complicated_fever_case",
    ),
    under5_complicated_fever_referred_proportion=dict(
        description="Proportion of Under-5s with complicated fever who were referred to clinic or hospital",
        title="% of Under-5s with complicated fever referred to clinic/hospital",
        numerator_slug="under5_complicated_fever_referred",
        denominator_slug="under5_complicated_fever",
    ),
    under1_check_ups_proportion=dict(
        description="Proportion of children Under-1 receiving on-time scheduled check-ups during the time period",
        title="% Under-1 receiving check-ups",
        numerator_slug="under1_visits_6weeks",
        denominator_slug="under1_cases_6weeks",
    ),
    under1_immunized_proportion=dict(
        description="Proportion of children under-1 reported as up-to-date on immunizations at " \
                    "last visit during the time period",
        title="% of Under-1 with up-to-date immunization",
        numerator_slug="under1_immunization_up_to_date",
        denominator_slug="under1_visits",
    ),
    under5_fever_rdt_negative_medicated_proportion=dict(
        description="Proportion of Under-5s with negative RDT result who received antimalarial/ADT medication",
        title="% Under-5s w/ Negative RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_negative_medicated",
        denominator_slug="under5_fever_rdt_negative"
    ),

    # Child Nutrition
    muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with moderate or severe wasting (MUAC < 125) "\
                    "at last MUAC reading this time period",
        title="% Under-5s with MUAC < 125",
        numerator_slug="child_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    muac_routine_proportion=dict(
        description="Proportion of children aged 6-59 months receiving on-time routine (every 30 days) MUAC "\
                    "readings during the time period",
        title="% Under-5s receiving on-time MUAC (30 days)",
        numerator_slug="child_muac_routine",
        denominator_slug="num_children_6to59months"
    ),
    under6month_exclusive_breastfeeding_proportion=dict(
        description="Proportion of children under 6 months reported as exclusively breast-fed at last " \
                    "visit during the time period",
        title="% Under-6-Months reported as exclusively breast-fed",
        numerator_slug="under6month_exclusive_breastfeeding",
        denominator_slug="under6month_visits",
    ),
    low_birth_weight_proportion=dict(
        description="Proportion of low birth weight (<2.5 kg) babies born during the time period",
        title="% low birth weight (<2.5 kg) babies born during the time period",
        numerator_slug="low_birth_weight",
        denominator_slug="birth_weight_registration",
    ),

    # CHW Visits
    households_routine_visit_past90days=dict(
        description="Proportion of Households receiving on-time routine visit within last 90 DAYS",
        title="% of HHs receiving visit in last 90 DAYS",
        numerator_slug="household_visits_90days",
        denominator_slug="household_cases_90days"
    ),
    households_routine_visit_past30days=dict(
        description="Proportion of Households receiving on-time routine visit within last 30 DAYS",
        title="% of HHs receiving visit in last 30 DAYS",
        numerator_slug="household_visits_30days",
        denominator_slug="household_cases_30days"
    ),
    under5_routine_visit_past30days=dict(
        description="Proportion of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        title="% of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="under5_visits_30days",
        denominator_slug="under5_cases_30days"
    ),
    pregnant_routine_visit_past30days=dict(
        description="Proportion of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        title="% of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="pregnancy_visits_30days",
        denominator_slug="pregnancy_cases_30days"
    ),
    neonate_routine_visit_past7days=dict(
        description="Proportion of NEONATES (NEWBORN LESS THAN 29 DAYS OLD) receiving on-time" \
                    " routine visit within last 7 DAYS",
        title="% of NEONATES (NEWBORN LESS THAN 29 DAYS OLD) receiving on-time routine visit " \
              "within last 7 DAYS",
        numerator_slug="neonate_visits_7days",
        denominator_slug="neonate_cases_7days"
    ),
    newborn_7day_visit_proportion=dict(
        description=" Proportion of children (LESS THAN 8 DAYS OLD) receiving first CHW check-up" \
		    "within 7 days of birth during the time period",
        title="% Newborns checked within 7 days of birth",
        numerator_slug="newborn_visits",
        denominator_slug="num_newborns"
    ),
    pregnancy_visit_danger_sign_referral_proportion=dict(
        description="Proportion of Pregnant Women Referred for Danger Signs",
        title="% Pregnant Women Referred for Danger Signs",
        numerator_slug="pregnancy_visit_danger_sign_referral",
        denominator_slug="pregnancy_visit_danger_sign",
    ),

    # Followups
    urgent_referrals_proportion=dict(
        description="Proportion of urgent referrals (codes A, E, B) or treatment receiving CHW " \
                    "follow-up within 2 days of referral / treatment during the time period",
        title="% Referred / Treated receiving on-time follow-up (within 2 days)",
        numerator_slug="urgent_referral_followups",
        denominator_slug="num_urgent_referrals"
    ),
    late_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving LATE follow-up (within 3-7 days)",
        title="% Referred / Treated receiving LATE follow-up (within 3-7 days)",
        numerator_slug="num_late_followups",
        denominator_slug="num_urgent_referrals",
    ),
    no_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving NO follow-up",
        title="% Referred / Treated receiving NO follow-up",
        numerator_slug="num_none_followups",
        denominator_slug="num_urgent_referrals",
    ),

    # Maternal Health
    family_planning_proportion=dict(
        description="Proportion of women 15-49 years old reporting use of " \
                    "modern family planning method at last visit this time period",
        title="% women 15-49 years old reporting use of modern family planning method",
        numerator_slug="household_num_fp",
        denominator_slug="household_num_ec"
    ),
    anc4_proportion=dict(
        description="Proportion of Pregnant women reporting at least four (4) Antenatal Care " \
                    "visit by 8 months of gestation this time period",
        title="% of Pregnant receiving 4 ANC visits to facility by 8 months gestation",
        numerator_slug="edd_soon_anc4",
        denominator_slug="edd_soon_visit"
    ),
    no_anc_proportion=dict(
        description="Proportion of Pregnant women reporting no Antenatal Care visit by " \
                    "4 months of gestation this time period",
        title="% Pregnant women reporting no Antenatal Care visit by 4 months of gestation",
        numerator_slug="no_anc",
        denominator_slug="anc_visit_120"
    ),
    facility_births_proportion=dict(
        description="Proportion of Births delivered in a Health Facility during the time period",
        title="% Births delivered in Health Facility",
        numerator_slug="num_births_registered_in_facility",
        denominator_slug="num_births_registered"
    ),
    pregnant_routine_checkup_proportion_6weeks=dict(
        description="Proportion of Pregnant women receiving on-time routine check-up (every 6 weeks)",
        title="% Pregnant receiving CHW visit in last 6 weeks",
        numerator_slug="pregnancy_visits_6weeks",
        denominator_slug="pregnancy_cases_6weeks",
    ),

    # Over5 Health
    over5_positive_rdt_medicated_proportion=dict(
        description="Proportion of Over-5s with positive RDT result who received antimalarial/ADT medication",
        title="% of Over-5s with positive RDT result who received antimalarial/ADT medication",
        numerator_slug="over5_positive_rdt_medicated",
        denominator_slug="over5_positive_rdt",
    ),
)
<commit_msg>change title for malaria cases<commit_after>COMPOSITE_INDICATORS = dict(
    # Child Health
    under5_fever_rdt_proportion=dict(
        description="Proportion of children aged 6-59 months with "
                    "uncomplicated fever who received RDT test",
        title="% Under-5s w/ uncomplicated fever who received RDT test",
        numerator_slug="under5_fever_rdt",
        denominator_slug="under5_fever"
    ),
    under5_fever_rdt_positive_proportion=dict(
        description="Proportion of children aged 6-59 months with uncomplicated"
                    " fever who received RDT test and were RDT positive",
        title="% Under-5s with uncomplicated fever who received RDT test and were RDT positive",
        numerator_slug="under5_fever_rdt_positive",
        denominator_slug="under5_fever_rdt"
    ),
    under5_fever_rdt_positive_medicated_proportion=dict(
        description="Proportion of children aged 6-59 months with positive RDT"
                    " result who received antimalarial/ADT medication",
        title="% Under-5s w/ Positive RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_positive_medicated",
        denominator_slug="under5_fever_rdt_positive"
    ),
    under5_fever_rdt_not_received_proportion=dict(
        description="Proportion of children aged 6-59 months with uncomplicated"
                    " fever who did NOT receive RDT test due to 'RDT not available' with CHW",
        title="% Under-5s w/ RDT Not Available",
        numerator_slug="under5_fever_rdt_not_received",
        denominator_slug="under5_fever"
    ),
    under5_diarrhea_ors_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ORS",
        title="% Under-5s with uncomplicated diarrhea who received ORS",
        numerator_slug="under5_diarrhea_ors",
        denominator_slug="under5_diarrhea"
    ),
    under5_diarrhea_zinc_proportion=dict(
        description="Proportion of children aged 2-59 months with "
                    "uncomplicated diarrhea who received ZINC",
        title="% Under-5s with uncomplicated diarrhea who received ZINC",
        numerator_slug="under5_diarrhea_zinc",
        denominator_slug="under5_diarrhea"
    ),
    under5_complicated_fever_facility_followup_proportion=dict(
        description="Proportion of children who attended follow-up at facility after being referred"\
                    " for complicated fever",
        title="% Under-5 attending follow-up at facility after complicated fever referral",
        numerator_slug="under5_complicated_fever_facility_followup",
        denominator_slug="under5_complicated_fever_case",
    ),
    under5_complicated_fever_referred_proportion=dict(
        description="Proportion of Under-5s with complicated fever who were referred to clinic or hospital",
        title="% of Under-5s with complicated fever referred to clinic/hospital",
        numerator_slug="under5_complicated_fever_referred",
        denominator_slug="under5_complicated_fever",
    ),
    under1_check_ups_proportion=dict(
        description="Proportion of children Under-1 receiving on-time scheduled check-ups during the time period",
        title="% Under-1 receiving check-ups",
        numerator_slug="under1_visits_6weeks",
        denominator_slug="under1_cases_6weeks",
    ),
    under1_immunized_proportion=dict(
        description="Proportion of children under-1 reported as up-to-date on immunizations at " \
                    "last visit during the time period",
        title="% of Under-1 with up-to-date immunization",
        numerator_slug="under1_immunization_up_to_date",
        denominator_slug="under1_visits",
    ),
    under5_fever_rdt_negative_medicated_proportion=dict(
        description="Proportion of children aged 6-59 months with negative RDT"
                    " result who received antimalarial/ADT medication",
        title="% Under-5s w/ Negative RDT result who received antimalarial/ADT medication",
        numerator_slug="under5_fever_rdt_negative_medicated",
        denominator_slug="under5_fever_rdt_negative"
    ),

    # Child Nutrition
    muac_wasting_proportion=dict(
        description="Proportion of children aged 6-59 months with moderate or severe wasting (MUAC < 125) "\
                    "at last MUAC reading this time period",
        title="% Under-5s with MUAC < 125",
        numerator_slug="child_muac_wasting",
        denominator_slug="child_muac_reading"
    ),
    muac_routine_proportion=dict(
        description="Proportion of children aged 6-59 months receiving on-time routine (every 30 days) MUAC "\
                    "readings during the time period",
        title="% Under-5s receiving on-time MUAC (30 days)",
        numerator_slug="child_muac_routine",
        denominator_slug="num_children_6to59months"
    ),
    under6month_exclusive_breastfeeding_proportion=dict(
        description="Proportion of children under 6 months reported as exclusively breast-fed at last " \
                    "visit during the time period",
        title="% Under-6-Months reported as exclusively breast-fed",
        numerator_slug="under6month_exclusive_breastfeeding",
        denominator_slug="under6month_visits",
    ),
    low_birth_weight_proportion=dict(
        description="Proportion of low birth weight (<2.5 kg) babies born during the time period",
        title="% low birth weight (<2.5 kg) babies born during the time period",
        numerator_slug="low_birth_weight",
        denominator_slug="birth_weight_registration",
    ),

    # CHW Visits
    households_routine_visit_past90days=dict(
        description="Proportion of Households receiving on-time routine visit within last 90 DAYS",
        title="% of HHs receiving visit in last 90 DAYS",
        numerator_slug="household_visits_90days",
        denominator_slug="household_cases_90days"
    ),
    households_routine_visit_past30days=dict(
        description="Proportion of Households receiving on-time routine visit within last 30 DAYS",
        title="% of HHs receiving visit in last 30 DAYS",
        numerator_slug="household_visits_30days",
        denominator_slug="household_cases_30days"
    ),
    under5_routine_visit_past30days=dict(
        description="Proportion of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        title="% of UNDER-5 CHILDREN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="under5_visits_30days",
        denominator_slug="under5_cases_30days"
    ),
    pregnant_routine_visit_past30days=dict(
        description="Proportion of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        title="% of PREGNANT WOMEN receiving on-time routine visit within last 30 DAYS",
        numerator_slug="pregnancy_visits_30days",
        denominator_slug="pregnancy_cases_30days"
    ),
    neonate_routine_visit_past7days=dict(
        description="Proportion of NEONATES (NEWBORN LESS THAN 29 DAYS OLD) receiving on-time" \
                    " routine visit within last 7 DAYS",
        title="% of NEONATES (NEWBORN LESS THAN 29 DAYS OLD) receiving on-time routine visit " \
              "within last 7 DAYS",
        numerator_slug="neonate_visits_7days",
        denominator_slug="neonate_cases_7days"
    ),
    newborn_7day_visit_proportion=dict(
        description=" Proportion of children (LESS THAN 8 DAYS OLD) receiving first CHW check-up" \
		    "within 7 days of birth during the time period",
        title="% Newborns checked within 7 days of birth",
        numerator_slug="newborn_visits",
        denominator_slug="num_newborns"
    ),
    pregnancy_visit_danger_sign_referral_proportion=dict(
        description="Proportion of Pregnant Women Referred for Danger Signs",
        title="% Pregnant Women Referred for Danger Signs",
        numerator_slug="pregnancy_visit_danger_sign_referral",
        denominator_slug="pregnancy_visit_danger_sign",
    ),

    # Followups
    urgent_referrals_proportion=dict(
        description="Proportion of urgent referrals (codes A, E, B) or treatment receiving CHW " \
                    "follow-up within 2 days of referral / treatment during the time period",
        title="% Referred / Treated receiving on-time follow-up (within 2 days)",
        numerator_slug="urgent_referral_followups",
        denominator_slug="num_urgent_referrals"
    ),
    late_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving LATE follow-up (within 3-7 days)",
        title="% Referred / Treated receiving LATE follow-up (within 3-7 days)",
        numerator_slug="num_late_followups",
        denominator_slug="num_urgent_referrals",
    ),
    no_followups_proportion=dict(
        description="Proportion of Referred / Treated receiving NO follow-up",
        title="% Referred / Treated receiving NO follow-up",
        numerator_slug="num_none_followups",
        denominator_slug="num_urgent_referrals",
    ),

    # Maternal Health
    family_planning_proportion=dict(
        description="Proportion of women 15-49 years old reporting use of " \
                    "modern family planning method at last visit this time period",
        title="% women 15-49 years old reporting use of modern family planning method",
        numerator_slug="household_num_fp",
        denominator_slug="household_num_ec"
    ),
    anc4_proportion=dict(
        description="Proportion of Pregnant women reporting at least four (4) Antenatal Care " \
                    "visit by 8 months of gestation this time period",
        title="% of Pregnant receiving 4 ANC visits to facility by 8 months gestation",
        numerator_slug="edd_soon_anc4",
        denominator_slug="edd_soon_visit"
    ),
    no_anc_proportion=dict(
        description="Proportion of Pregnant women reporting no Antenatal Care visit by " \
                    "4 months of gestation this time period",
        title="% Pregnant women reporting no Antenatal Care visit by 4 months of gestation",
        numerator_slug="no_anc",
        denominator_slug="anc_visit_120"
    ),
    facility_births_proportion=dict(
        description="Proportion of Births delivered in a Health Facility during the time period",
        title="% Births delivered in Health Facility",
        numerator_slug="num_births_registered_in_facility",
        denominator_slug="num_births_registered"
    ),
    pregnant_routine_checkup_proportion_6weeks=dict(
        description="Proportion of Pregnant women receiving on-time routine check-up (every 6 weeks)",
        title="% Pregnant receiving CHW visit in last 6 weeks",
        numerator_slug="pregnancy_visits_6weeks",
        denominator_slug="pregnancy_cases_6weeks",
    ),

    # Over5 Health
    over5_positive_rdt_medicated_proportion=dict(
        description="Proportion of Over-5s with positive RDT result who received antimalarial/ADT medication",
        title="% of Over-5s with positive RDT result who received antimalarial/ADT medication",
        numerator_slug="over5_positive_rdt_medicated",
        denominator_slug="over5_positive_rdt",
    ),
)
<|endoftext|>


<commit_before>from django.contrib import admin
from .models import *

class MentorMenteePairInline(admin.TabularInline):
    model = MentorMenteePairs
    fields = (
        'mentor',
        'mentee',
        'start_date',
        'end_date',
    )

class MentorContactInline(admin.StackedInline):
    model = MentorContactInformation
    fieldsets = (
        ('Email', {'fields': ('primary_email', 'secondary_email')}),
        ('Phone', {'fields': ('primary_phone', 'secondary_phone')}),
        ('Web Contact', {'fields': ('linkedin_url', 'facebook_url', 'personal_url')}),
        ('Address', {'fields': ('street_address', 'city', 'state')}),
    )

class MentorEducationInline(admin.TabularInline):
    model = MentorEducation
    extra = 1
    fields = (
        'school',
        'major1',
        'major2',
        'minor1',
        'minor2',
        'degree',
        'graduation_year'
    )

class MentorCareerInline(admin.TabularInline):
    model = MentorEmployment
    extra = 1
    fields = (
        'company',
        'title',
        'description'
    )

class MentorPreferenceInline(admin.TabularInline):
    model = MentorPreference
    fields = (
        'first_choice',
        'second_choice',
        'third_choice',
        'preferred_communication'
    )

@admin.register(Mentor)
class MentorAdmin(admin.ModelAdmin):
    fields = (
        'first_name',
        'last_name',
        'gender'
        'approved',
        'confirmed',
        'confirmation_token',
        'active_until',
    )
    list_display = ('first_name', 'last_name', 'gender', 'approved', 'confirmed')

    inlines = [
        MentorContactInline,
        MentorEducationInline,
        MentorCareerInline,
        MentorPreferenceInline,
        MentorMenteePairInline,
    ]

class MenteeContactInline(admin.StackedInline):
    model = MenteeContactInformation
    fieldsets = (
        ('Email', {'fields': ('primary_email', 'secondary_email')}),
        ('Phone', {'fields': ('primary_phone', 'secondary_phone')}),
        ('Web Contact', {'fields': ('linkedin_url', 'facebook_url', 'personal_url')}),
        ('Address', {'fields': ('street_address', 'city', 'state')}),
    )

class MenteeEducationInline(admin.TabularInline):
    model = MenteeEducation
    extra = 1
    fields = (
        'school',
        'major1',
        'major2',
        'minor1',
        'minor2',
        'graduation_year'
    )

class MenteePreferenceInline(admin.TabularInline):
    model = MenteePreference
    fields = (
        'first_choice',
        'second_choice',
        'third_choice',
        'preferred_communication'
    )

@admin.register(Mentee)
class MenteeAdmin(admin.ModelAdmin):
    fields = (
        'first_name',
        'last_name',
        'gender',
        'approved',
        'confirmed',
        'confirmation_token',
        'active_until',
    )
    list_display = ('first_name', 'last_name', 'gender', 'approved', 'confirmed')

    inlines = [
        MenteeContactInline,
        MenteeEducationInline,
        MenteePreferenceInline,
        MentorMenteePairInline,
    ]

@admin.register(Feedback)
class FeedbackAdmin(admin.ModelAdmin):
    fields = (
        'pairing',
        'token',
        'giver',
        'went_well',
        'went_poorly',
        'other',
    )
    list_display = fields

class FeedbackInline(admin.TabularInline):
    model = Feedback
    extra = 0
    fields = (
        'giver',
        'went_well',
        'went_poorly',
        'other'
    )

@admin.register(MentorMenteePairs)
class MentorMenteePairsAdmin(admin.ModelAdmin):
    fields = (
        'mentor',
        'mentee',
        'start_date',
        'end_date'
    )
    list_display = fields
    inlines = [
        FeedbackInline
    ]

<commit_msg>added missing comma<commit_after>from django.contrib import admin
from .models import *

class MentorMenteePairInline(admin.TabularInline):
    model = MentorMenteePairs
    fields = (
        'mentor',
        'mentee',
        'start_date',
        'end_date',
    )

class MentorContactInline(admin.StackedInline):
    model = MentorContactInformation
    fieldsets = (
        ('Email', {'fields': ('primary_email', 'secondary_email')}),
        ('Phone', {'fields': ('primary_phone', 'secondary_phone')}),
        ('Web Contact', {'fields': ('linkedin_url', 'facebook_url', 'personal_url')}),
        ('Address', {'fields': ('street_address', 'city', 'state')}),
    )

class MentorEducationInline(admin.TabularInline):
    model = MentorEducation
    extra = 1
    fields = (
        'school',
        'major1',
        'major2',
        'minor1',
        'minor2',
        'degree',
        'graduation_year'
    )

class MentorCareerInline(admin.TabularInline):
    model = MentorEmployment
    extra = 1
    fields = (
        'company',
        'title',
        'description'
    )

class MentorPreferenceInline(admin.TabularInline):
    model = MentorPreference
    fields = (
        'first_choice',
        'second_choice',
        'third_choice',
        'preferred_communication'
    )

@admin.register(Mentor)
class MentorAdmin(admin.ModelAdmin):
    fields = (
        'first_name',
        'last_name',
        'gender',
        'approved',
        'confirmed',
        'confirmation_token',
        'active_until',
    )
    list_display = ('first_name', 'last_name', 'gender', 'approved', 'confirmed')

    inlines = [
        MentorContactInline,
        MentorEducationInline,
        MentorCareerInline,
        MentorPreferenceInline,
        MentorMenteePairInline,
    ]

class MenteeContactInline(admin.StackedInline):
    model = MenteeContactInformation
    fieldsets = (
        ('Email', {'fields': ('primary_email', 'secondary_email')}),
        ('Phone', {'fields': ('primary_phone', 'secondary_phone')}),
        ('Web Contact', {'fields': ('linkedin_url', 'facebook_url', 'personal_url')}),
        ('Address', {'fields': ('street_address', 'city', 'state')}),
    )

class MenteeEducationInline(admin.TabularInline):
    model = MenteeEducation
    extra = 1
    fields = (
        'school',
        'major1',
        'major2',
        'minor1',
        'minor2',
        'graduation_year'
    )

class MenteePreferenceInline(admin.TabularInline):
    model = MenteePreference
    fields = (
        'first_choice',
        'second_choice',
        'third_choice',
        'preferred_communication'
    )

@admin.register(Mentee)
class MenteeAdmin(admin.ModelAdmin):
    fields = (
        'first_name',
        'last_name',
        'gender',
        'approved',
        'confirmed',
        'confirmation_token',
        'active_until',
    )
    list_display = ('first_name', 'last_name', 'gender', 'approved', 'confirmed')

    inlines = [
        MenteeContactInline,
        MenteeEducationInline,
        MenteePreferenceInline,
        MentorMenteePairInline,
    ]

@admin.register(Feedback)
class FeedbackAdmin(admin.ModelAdmin):
    fields = (
        'pairing',
        'token',
        'giver',
        'went_well',
        'went_poorly',
        'other',
    )
    list_display = fields

class FeedbackInline(admin.TabularInline):
    model = Feedback
    extra = 0
    fields = (
        'giver',
        'went_well',
        'went_poorly',
        'other'
    )

@admin.register(MentorMenteePairs)
class MentorMenteePairsAdmin(admin.ModelAdmin):
    fields = (
        'mentor',
        'mentee',
        'start_date',
        'end_date'
    )
    list_display = fields
    inlines = [
        FeedbackInline
    ]

<|endoftext|>


<commit_before>from cad import CAD
from sympy import And, Or, Not, Min, Max, Add, Mul, Pow, Lt, Le, Gt, Ge, \
                  Eq, Ne, S, Integer, Rational, Symbol, Expr as SymPyExpr
from sympy.logic.boolalg import BooleanFunction, BooleanAtom, \
                                BooleanTrue, BooleanFalse
import operator

def is_min_max(s):
  return isinstance(s, Min) or isinstance(s, Max)

def get_min_max(s, invert=False):
  if isinstance(s, Min):
    return (Min if not invert else Max)
  if isinstance(s, Max):
    return (Max if not invert else Min)
  return None

def apply_and_simplify(s, e, op, invert_on_negative=False):
  s_cons = get_min_max(s)
  s_cons_inv = get_min_max(s, invert=True)
  e_cons = get_min_max(e)
  e_cons_inv = get_min_max(e, invert=True)

  def without_invert_on_negative():
    # Min/Max op Min/Max
    if s_cons != None and e_cons != None:
      args = []
      # Min op Min or Max op Max
      if s_cons == e_cons:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, ea))
      # Min op Max
      else:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, -ea))
      return s_cons(*args)

    # Min/Max op Sym
    if s_cons != None and isinstance(e, Symbol):
      return s_cons(*map(lambda a: op(a, e), s.args))
    # Sym op Min/Max
    if e_cons != None and isinstance(s, Symbol):
      return e_cons(*map(lambda a: op(s, a), e.args))

    # Min/Max op Int
    if s_cons != None and isinstance(e, Integer):
      return s_cons(*map(lambda a: op(a, e), s.args))
    # Int op Min/Max
    if e_cons != None and isinstance(s, Integer):
      return e_cons(*map(lambda a: op(s, a), e.args))

    return op(s, e)

  def with_invert_on_negative():
    # Min/Max op Min/Max
    if s_cons != None and e_cons != None:
      args = []
      # Min op Min or Max op Max
      if s_cons == e_cons:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, ea))
        for sa in s.args:
          for ea in e.args:
            args.append(op(-sa, ea))
      # Min op Max
      else:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, -ea))
        for sa in s.args:
          for ea in e.args:
            args.append(op(-sa, -ea))
      return s_cons(*args)

    # Min/Max op Sym
    if s_cons != None and isinstance(e, Symbol):
      args = map(lambda a: op(a, e), s.args) \
          + map(lambda a: op(a, -e), s.args)
      return s_cons(*args)
    # Sym op Min/Max
    if e_cons != None and isinstance(s, Symbol):
      args = map(lambda a: op(s, a), e.args) \
          + map(lambda a: op(-s, a), e.args)
      return e_cons(*args)

    # Min/Max op Int
    if s_cons != None and isinstance(e, Integer):
      cons = s_cons_inv if e < 0 else s_cons
      return cons(*map(lambda a: op(a, e), s.args))
    # Int op Min/Max
    if e_cons != None and isinstance(s, Integer):
      cons = e_cons_inv if s < 0 else e_cons
      return cons(*map(lambda a: op(s, a), e.args))

    return op(s, e)

  if invert_on_negative:
    return with_invert_on_negative()
  return without_invert_on_negative()

class Expr(object):
  initialized = False

  @staticmethod
  def init():
    # FIXME: Are (+-)oo correctly handled?
    Expr.__add__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.add))
    Expr.__sub__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.sub))
    Expr.__mul__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.mul, \
            invert_on_negative=True))
    Expr.__div__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.div, \
            invert_on_negative=True))
    Expr.__pow__ = lambda s, e: Expr(s.expr ** e.expr)
    Expr.__neg__ = lambda s: Expr(-s.expr)

    Expr.__eq__ = lambda s, e: Expr(Eq(s.expr, e.expr))
    Expr.__ne__ = lambda s, e: Expr(Ne(s.expr, e.expr))
    Expr.__lt__ = lambda s, e: Expr(Lt(s.expr, e.expr))
    Expr.__le__ = lambda s, e: Expr(Le(s.expr, e.expr))
    Expr.__gt__ = lambda s, e: Expr(Gt(s.expr, e.expr))
    Expr.__ge__ = lambda s, e: Expr(Ge(s.expr, e.expr))

    Expr.__and__    = lambda s, e: Expr(And(s.expr, e.expr))
    Expr.__or__     = lambda s, e: Expr(Or(s.expr,  e.expr))
    Expr.__invert__ = lambda s:    Expr(Not(s.expr))

    Expr.is_eq       = lambda s, e: s.expr == e.expr
    Expr.is_ne       = lambda s, e: s.expr != e.expr
    Expr.is_empty    = lambda s: s.is_eq(Expr.empty)

    Expr.is_inf       = lambda s: s.expr == S.Infinity or s.expr == -S.Infinity
    Expr.is_plus_inf  = lambda s: s.expr == S.Infinity
    Expr.is_minus_inf = lambda s: s.expr == -S.Infinity

    Expr.is_constant = lambda s: isinstance(s.expr, Integer)
    Expr.is_integer  = lambda s: isinstance(s.expr, Integer)
    Expr.is_rational = lambda s: isinstance(s.expr, Rational)
    Expr.is_symbol   = lambda s: isinstance(s.expr, Symbol)

    Expr.is_min = lambda s: isinstance(s.expr, Min)
    Expr.is_max = lambda s: isinstance(s.expr, Max)
    Expr.is_add = lambda s: isinstance(s.expr, Add)
    Expr.is_mul = lambda s: isinstance(s.expr, Mul)
    Expr.is_pow = lambda s: isinstance(s.expr, Pow)

    Expr.get_integer = lambda s: s.expr.p
    Expr.get_numer   = lambda s: s.expr.p
    Expr.get_denom   = lambda s: s.expr.q

    Expr.get_name = lambda s: s.expr.name

    Expr.compare = lambda s, e: s.compare(e)

    # Empty. When min/max is invalid.
    Expr.empty = Expr("EMPTY")

  @staticmethod
  def get_nan():
    return Expr(S.NaN)

  @staticmethod
  def get_plus_inf():
    return Expr(S.Infinity)

  @staticmethod
  def get_minus_inf():
    return Expr(-S.Infinity)

  @staticmethod
  def get_true():
    return Expr(True)

  @staticmethod
  def get_false():
    return Expr(False)

  def __init__(self, val):
    if not Expr.initialized:
      Expr.initialized = True
      Expr.init()

    if isinstance(val, int) or isinstance(val, long):
      self.expr = Integer(val)
    elif isinstance(val, basestring):
      self.expr = Symbol(val)
    elif isinstance(val, bool) or isinstance(val, BooleanAtom):
      self.expr = S.One if val else S.Zero
    else:
      assert isinstance(val, SymPyExpr) or isinstance(val, BooleanFunction) \
             or (val == S.Infinity) or (val == -S.Infinity)
      self.expr = val

  def __str__(self):
    return self.expr.__str__()

  def __repr__(self):
    r = self.__str__()
    return r

  def subs(self, expr_from, expr_to):
    return Expr(self.expr.subs([(expr_from.expr, expr_to.expr)]))

  def args(self):
    return map(Expr, self.expr.args)

  def sympy(self):
    return self.expr

  @staticmethod
  def reduce_conditional(expr):
      if isinstance(expr, And):
        # And(x, y)
        x, y = expr.args
        # And(Or(a, b), y)
        if isinstance(x, Or):
          a, b = x.args
          # And(Or(a, b), Or(c, d))
          if isinstance(y, Or):
            c, d = y.args
            return [[a, c], [a, d], [b, c], [b, d]]
        # And(Or(a, b), y)
        red_args = map(reduce_contional, expr.args)
        red_args = sum(red_args, [])
        return red_args
      elif isinstance(expr.expr, Or):
        red_args = map(reduce_contional, expr.args)
        return red_args
      return expr

  @staticmethod
  def minmax_args(expr, ty):
    if isinstance(expr, ty):
      return list(expr.args)
    return [expr]

  def reduce_min(self, args, assumptions):
    m = Min(*args)

    if not isinstance(m, Min):
      # Expression was simplified.
      return [m]

    del_args = [False] * len(args)
    for i in xrange(len(args)):
      if del_args[i]: continue
      for j in xrange(i + 1, len(args)):
         if del_args[j]: continue

         rest = CAD.implies(assumptions, args[i] <= args[j])
         resf = CAD.implies(assumptions, args[i] >= args[j])
         resi = CAD.implies(assumptions, args[i] >  args[j])

         if not (CAD.is_unknown(rest) or CAD.is_unknown(resi)) \
             and CAD.is_true(rest) and CAD.is_true(resi):
           del_args[i] = True
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_true(rest) or CAD.is_false(resf)):
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_false(rest) or CAD.is_true(resf)):
           del_args[i] = True

    res_args = [args[i] for i in xrange(len(args)) if not del_args[i]]
    return res_args

  def reduce_max(self, args, assumptions):
    m = Max(*args)

    if not isinstance(m, Max):
      # Expression was simplified.
      return [m]

    del_args = [False] * len(args)
    for i in xrange(len(args)):
      if del_args[i]: continue
      for j in xrange(i + 1, len(args)):
         if del_args[j]: continue

         rest = CAD.implies(assumptions, args[i] >= args[j])
         resf = CAD.implies(assumptions, args[i] <= args[j])
         resi = CAD.implies(assumptions, args[i] <  args[j])

         if not (CAD.is_unknown(rest) or CAD.is_unknown(resi)) \
             and CAD.is_true(rest) and CAD.is_true(resi):
           del_args[i] = True
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_true(rest) or CAD.is_false(resf)):
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_false(rest) or CAD.is_true(resf)):
           del_args[i] = True

    res_args = [args[i] for i in xrange(len(args)) if not del_args[i]]
    return res_args

  def min_or_max(self, other, op, assumptions):
    try:
      assert op == Min or op == Max
      args = Expr.minmax_args(self.expr, op) + \
             Expr.minmax_args(other.expr, op)

      inv_op = Min if op == Max else Max
      if isinstance(other.expr, inv_op):
        if self.expr in other.expr.args:
          return self
      if isinstance(self.expr, inv_op) and other.expr in self.expr.args:
        return other

      if (self.expr == S.Infinity):
        return other
      elif (other.expr == S.Infinity):
        return self

      if (self.expr == -S.Infinity):
        return self
      elif (other.expr == -S.Infinity):
        return other

      # TODO: handle min/max parameters.
      if any(map(lambda e: e.has(Min) or e.has(Max), args)):
        return Expr(op(self.expr, other.expr))

      if op == Min:
        res_args = \
          self.reduce_min(args, assumptions.expr if assumptions else False)
      else:
        res_args = \
          self.reduce_max(args, assumptions.expr if assumptions else False)
      if not res_args:
        return Expr.empty
      return Expr(op(*res_args))
    except BaseException as b:
      print "Exception triggered: min_or_max", self, other
      print b
      raise

  def min(self, other, assumptions=None):
    return self.min_or_max(other, Min, assumptions)

  def max(self, other, assumptions=None):
    return self.min_or_max(other, Max, assumptions)

<commit_msg>Use the reduced argument list for min/max ops<commit_after>from cad import CAD
from sympy import And, Or, Not, Min, Max, Add, Mul, Pow, Lt, Le, Gt, Ge, \
                  Eq, Ne, S, Integer, Rational, Symbol, Expr as SymPyExpr
from sympy.logic.boolalg import BooleanFunction, BooleanAtom, \
                                BooleanTrue, BooleanFalse
import operator

def is_min_max(s):
  return isinstance(s, Min) or isinstance(s, Max)

def get_min_max(s, invert=False):
  if isinstance(s, Min):
    return (Min if not invert else Max)
  if isinstance(s, Max):
    return (Max if not invert else Min)
  return None

def apply_and_simplify(s, e, op, invert_on_negative=False):
  s_cons = get_min_max(s)
  s_cons_inv = get_min_max(s, invert=True)
  e_cons = get_min_max(e)
  e_cons_inv = get_min_max(e, invert=True)

  def without_invert_on_negative():
    # Min/Max op Min/Max
    if s_cons != None and e_cons != None:
      args = []
      # Min op Min or Max op Max
      if s_cons == e_cons:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, ea))
      # Min op Max
      else:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, -ea))
      return s_cons(*args)

    # Min/Max op Sym
    if s_cons != None and isinstance(e, Symbol):
      return s_cons(*map(lambda a: op(a, e), s.args))
    # Sym op Min/Max
    if e_cons != None and isinstance(s, Symbol):
      return e_cons(*map(lambda a: op(s, a), e.args))

    # Min/Max op Int
    if s_cons != None and isinstance(e, Integer):
      return s_cons(*map(lambda a: op(a, e), s.args))
    # Int op Min/Max
    if e_cons != None and isinstance(s, Integer):
      return e_cons(*map(lambda a: op(s, a), e.args))

    return op(s, e)

  def with_invert_on_negative():
    # Min/Max op Min/Max
    if s_cons != None and e_cons != None:
      args = []
      # Min op Min or Max op Max
      if s_cons == e_cons:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, ea))
        for sa in s.args:
          for ea in e.args:
            args.append(op(-sa, ea))
      # Min op Max
      else:
        for sa in s.args:
          for ea in e.args:
            args.append(op(sa, -ea))
        for sa in s.args:
          for ea in e.args:
            args.append(op(-sa, -ea))
      return s_cons(*args)

    # Min/Max op Sym
    if s_cons != None and isinstance(e, Symbol):
      args = map(lambda a: op(a, e), s.args) \
          + map(lambda a: op(a, -e), s.args)
      return s_cons(*args)
    # Sym op Min/Max
    if e_cons != None and isinstance(s, Symbol):
      args = map(lambda a: op(s, a), e.args) \
          + map(lambda a: op(-s, a), e.args)
      return e_cons(*args)

    # Min/Max op Int
    if s_cons != None and isinstance(e, Integer):
      cons = s_cons_inv if e < 0 else s_cons
      return cons(*map(lambda a: op(a, e), s.args))
    # Int op Min/Max
    if e_cons != None and isinstance(s, Integer):
      cons = e_cons_inv if s < 0 else e_cons
      return cons(*map(lambda a: op(s, a), e.args))

    return op(s, e)

  if invert_on_negative:
    return with_invert_on_negative()
  return without_invert_on_negative()

class Expr(object):
  initialized = False

  @staticmethod
  def init():
    # FIXME: Are (+-)oo correctly handled?
    Expr.__add__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.add))
    Expr.__sub__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.sub))
    Expr.__mul__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.mul, \
            invert_on_negative=True))
    Expr.__div__ = \
        lambda s, e: Expr(apply_and_simplify(s.expr, e.expr, operator.div, \
            invert_on_negative=True))
    Expr.__pow__ = lambda s, e: Expr(s.expr ** e.expr)
    Expr.__neg__ = lambda s: Expr(-s.expr)

    Expr.__eq__ = lambda s, e: Expr(Eq(s.expr, e.expr))
    Expr.__ne__ = lambda s, e: Expr(Ne(s.expr, e.expr))
    Expr.__lt__ = lambda s, e: Expr(Lt(s.expr, e.expr))
    Expr.__le__ = lambda s, e: Expr(Le(s.expr, e.expr))
    Expr.__gt__ = lambda s, e: Expr(Gt(s.expr, e.expr))
    Expr.__ge__ = lambda s, e: Expr(Ge(s.expr, e.expr))

    Expr.__and__    = lambda s, e: Expr(And(s.expr, e.expr))
    Expr.__or__     = lambda s, e: Expr(Or(s.expr,  e.expr))
    Expr.__invert__ = lambda s:    Expr(Not(s.expr))

    Expr.is_eq       = lambda s, e: s.expr == e.expr
    Expr.is_ne       = lambda s, e: s.expr != e.expr
    Expr.is_empty    = lambda s: s.is_eq(Expr.empty)

    Expr.is_inf       = lambda s: s.expr == S.Infinity or s.expr == -S.Infinity
    Expr.is_plus_inf  = lambda s: s.expr == S.Infinity
    Expr.is_minus_inf = lambda s: s.expr == -S.Infinity

    Expr.is_constant = lambda s: isinstance(s.expr, Integer)
    Expr.is_integer  = lambda s: isinstance(s.expr, Integer)
    Expr.is_rational = lambda s: isinstance(s.expr, Rational)
    Expr.is_symbol   = lambda s: isinstance(s.expr, Symbol)

    Expr.is_min = lambda s: isinstance(s.expr, Min)
    Expr.is_max = lambda s: isinstance(s.expr, Max)
    Expr.is_add = lambda s: isinstance(s.expr, Add)
    Expr.is_mul = lambda s: isinstance(s.expr, Mul)
    Expr.is_pow = lambda s: isinstance(s.expr, Pow)

    Expr.get_integer = lambda s: s.expr.p
    Expr.get_numer   = lambda s: s.expr.p
    Expr.get_denom   = lambda s: s.expr.q

    Expr.get_name = lambda s: s.expr.name

    Expr.compare = lambda s, e: s.compare(e)

    # Empty. When min/max is invalid.
    Expr.empty = Expr("EMPTY")

  @staticmethod
  def get_nan():
    return Expr(S.NaN)

  @staticmethod
  def get_plus_inf():
    return Expr(S.Infinity)

  @staticmethod
  def get_minus_inf():
    return Expr(-S.Infinity)

  @staticmethod
  def get_true():
    return Expr(True)

  @staticmethod
  def get_false():
    return Expr(False)

  def __init__(self, val):
    if not Expr.initialized:
      Expr.initialized = True
      Expr.init()

    if isinstance(val, int) or isinstance(val, long):
      self.expr = Integer(val)
    elif isinstance(val, basestring):
      self.expr = Symbol(val)
    elif isinstance(val, bool) or isinstance(val, BooleanAtom):
      self.expr = S.One if val else S.Zero
    else:
      assert isinstance(val, SymPyExpr) or isinstance(val, BooleanFunction) \
             or (val == S.Infinity) or (val == -S.Infinity)
      self.expr = val

  def __str__(self):
    return self.expr.__str__()

  def __repr__(self):
    r = self.__str__()
    return r

  def subs(self, expr_from, expr_to):
    return Expr(self.expr.subs([(expr_from.expr, expr_to.expr)]))

  def args(self):
    return map(Expr, self.expr.args)

  def sympy(self):
    return self.expr

  @staticmethod
  def reduce_conditional(expr):
      if isinstance(expr, And):
        # And(x, y)
        x, y = expr.args
        # And(Or(a, b), y)
        if isinstance(x, Or):
          a, b = x.args
          # And(Or(a, b), Or(c, d))
          if isinstance(y, Or):
            c, d = y.args
            return [[a, c], [a, d], [b, c], [b, d]]
        # And(Or(a, b), y)
        red_args = map(reduce_contional, expr.args)
        red_args = sum(red_args, [])
        return red_args
      elif isinstance(expr.expr, Or):
        red_args = map(reduce_contional, expr.args)
        return red_args
      return expr

  @staticmethod
  def minmax_args(expr, ty):
    if isinstance(expr, ty):
      return list(expr.args)
    return [expr]

  def reduce_min(self, args, assumptions):
    m = Min(*args)

    if not isinstance(m, Min):
      # Expression was simplified.
      return [m]

    # Use the reduced argument list.
    args = m.args

    del_args = [False] * len(args)
    for i in xrange(len(args)):
      if del_args[i]: continue
      for j in xrange(i + 1, len(args)):
         if del_args[j]: continue

         rest = CAD.implies(assumptions, args[i] <= args[j])
         resf = CAD.implies(assumptions, args[i] >= args[j])
         resi = CAD.implies(assumptions, args[i] >  args[j])

         if not (CAD.is_unknown(rest) or CAD.is_unknown(resi)) \
             and CAD.is_true(rest) and CAD.is_true(resi):
           del_args[i] = True
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_true(rest) or CAD.is_false(resf)):
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_false(rest) or CAD.is_true(resf)):
           del_args[i] = True

    res_args = [args[i] for i in xrange(len(args)) if not del_args[i]]
    return res_args

  def reduce_max(self, args, assumptions):
    m = Max(*args)

    if not isinstance(m, Max):
      # Expression was simplified.
      return [m]

    # Use the reduced argument list.
    args = m.args

    del_args = [False] * len(args)
    for i in xrange(len(args)):
      if del_args[i]: continue
      for j in xrange(i + 1, len(args)):
         if del_args[j]: continue

         rest = CAD.implies(assumptions, args[i] >= args[j])
         resf = CAD.implies(assumptions, args[i] <= args[j])
         resi = CAD.implies(assumptions, args[i] <  args[j])

         if not (CAD.is_unknown(rest) or CAD.is_unknown(resi)) \
             and CAD.is_true(rest) and CAD.is_true(resi):
           del_args[i] = True
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_true(rest) or CAD.is_false(resf)):
           del_args[j] = True
         elif not (CAD.is_unknown(rest) or CAD.is_unknown(resf)) \
             and (CAD.is_false(rest) or CAD.is_true(resf)):
           del_args[i] = True

    res_args = [args[i] for i in xrange(len(args)) if not del_args[i]]
    return res_args

  def min_or_max(self, other, op, assumptions):
    try:
      assert op == Min or op == Max
      args = Expr.minmax_args(self.expr, op) + \
             Expr.minmax_args(other.expr, op)

      inv_op = Min if op == Max else Max
      if isinstance(other.expr, inv_op):
        if self.expr in other.expr.args:
          return self
      if isinstance(self.expr, inv_op) and other.expr in self.expr.args:
        return other

      if (self.expr == S.Infinity):
        return other
      elif (other.expr == S.Infinity):
        return self

      if (self.expr == -S.Infinity):
        return self
      elif (other.expr == -S.Infinity):
        return other

      # TODO: handle min/max parameters.
      if any(map(lambda e: e.has(Min) or e.has(Max), args)):
        return Expr(op(self.expr, other.expr))

      if op == Min:
        res_args = \
          self.reduce_min(args, assumptions.expr if assumptions else False)
      else:
        res_args = \
          self.reduce_max(args, assumptions.expr if assumptions else False)
      if not res_args:
        return Expr.empty
      return Expr(op(*res_args))
    except BaseException as b:
      print "Exception triggered: min_or_max", self, other
      print b
      raise

  def min(self, other, assumptions=None):
    return self.min_or_max(other, Min, assumptions)

  def max(self, other, assumptions=None):
    return self.min_or_max(other, Max, assumptions)

<|endoftext|>