def get_child_households_profile(geo_code, geo_level, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ['gender of head of household'], geo_level, geo_code, session, order_by='gender of head of household', table_name='genderofheadofhouseholdunder18') female_heads = head_gender_dist['Female']['numerators']['this'] # annual household income income_dist_data, _ = get_stat_data( ['annual household income'], geo_level, geo_code, session, exclude=['Unspecified'], recode=HOUSEHOLD_INCOME_RECODE, key_order=HOUSEHOLD_INCOME_RECODE.values(), table_name='annualhouseholdincomeunder18') # median income median = calculate_median_stat(income_dist_data) median_income = HOUSEHOLD_INCOME_ESTIMATE[median] # type of dwelling type_of_dwelling_dist, _ = get_stat_data( ['type of main dwelling'], geo_level, geo_code, session, recode=TYPE_OF_DWELLING_RECODE, order_by='-total') informal = type_of_dwelling_dist['Shack']['numerators']['this'] # size of household household_size_dist, _ = get_stat_data( ['household size', 'age of household head'], geo_level, geo_code, session ) return { 'total_households': { 'name': 'Households with heads under 18 years old', 'values': {'this': total_households}, }, 'type_of_dwelling_distribution': type_of_dwelling_dist, 'informal': { 'name': 'Child-headed households that are informal dwellings (shacks)', 'values': {'this': percent(informal, total_households)}, 'numerators': {'this': informal}, }, 'annual_income_distribution': income_dist_data, 'median_annual_income': { 'name': 'Average annual child-headed household income', 'values': {'this': median_income}, }, 'household_size_distribution': household_size_dist, 'head_of_household': { 'gender_distribution': head_gender_dist, 'female': { 'name': 'Child-headed households with women as their head', 'values': {'this': percent(female_heads, total_households)}, 'numerators': {'this': female_heads}, }, }, }
def revenue_breakdown(self): values = [] for year in self.years + [self.budget_year]: year_name = year if year != self.budget_year else ("%s budget" % year) subtotal = 0.0 try: total = self.results['revenue_breakdown']['1900'][year] for item, code in self.revenue_breakdown_items: amount = self.results['revenue_breakdown'][code][year] subtotal += amount values.append({ 'item': item, 'amount': amount, 'percent': percent(amount, total), 'year': year_name, }) if total and subtotal and (total != subtotal): values.append({ 'item': 'Other', 'amount': total - subtotal, 'percent': percent(total - subtotal, total), 'year': year_name, }) except KeyError: continue return values
def get_households_profile(geo, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ['gender of household head'], geo, session, order_by='gender of household head') female_heads = head_gender_dist['Female']['numerators']['this'] # age db_model_u18 = get_model_from_fields( ['gender of head of household'], geo.geo_level, table_name='genderofheadofhouseholdunder18' ) objects = get_objects_by_geo(db_model_u18, geo, session) total_under_18 = float(sum(o[0] for o in objects)) # type of dwelling type_of_dwelling_dist, _ = get_stat_data( ['type of dwelling'], geo, session, recode=TYPE_OF_DWELLING_RECODE, order_by='-total') informal = type_of_dwelling_dist['Shack']['numerators']['this'] _, total_ecd_children = get_stat_data( ['age in completed years'], geo, session, table_name='ageincompletedyears', only=['0', '1', '2', '3', '4', '5']) ecd_children_per_household = ratio(total_ecd_children, total_households) return { 'total_households': { 'name': 'Households', 'values': {'this': total_households}, }, 'type_of_dwelling_distribution': type_of_dwelling_dist, 'informal': { 'name': 'Households that are informal dwellings (shacks)', 'values': {'this': percent(informal, total_households)}, 'numerators': {'this': informal}, }, 'head_of_household': { 'gender_distribution': head_gender_dist, 'female': { 'name': 'Households with women as their head', 'values': {'this': percent(female_heads, total_households)}, 'numerators': {'this': female_heads}, }, 'under_18': { 'name': 'Households with heads under 18 years old', 'values': {'this': total_under_18}, } }, 'ecd_children_per_household': { 'name': 'Average number of children (aged 0-5) in each household', 'values': {'this': ecd_children_per_household}, }, }
def get_child_households_profile(geo, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ['gender of head of household'], geo, session, order_by='gender of head of household', table_name='genderofheadofhouseholdunder18') female_heads = head_gender_dist['Female']['numerators']['this'] # annual household income if geo.version == '2011': HOUSEHOLD_INCOME_RECODE = HOUSEHOLD_INCOME_RECODE_2011 else: HOUSEHOLD_INCOME_RECODE = COLLAPSED_ANNUAL_INCOME_CATEGORIES income_dist_data, _ = get_stat_data( ['annual household income'], geo, session, exclude=['Unspecified'], recode=HOUSEHOLD_INCOME_RECODE, key_order=HOUSEHOLD_INCOME_RECODE.values(), table_name='annualhouseholdincomeunder18') # median income median = calculate_median_stat(income_dist_data) median_income = HOUSEHOLD_INCOME_ESTIMATE[median] # type of dwelling type_of_dwelling_dist, _ = get_stat_data( ['type of main dwelling'], geo, session, recode=TYPE_OF_DWELLING_RECODE, order_by='-total') informal = type_of_dwelling_dist['Shack']['numerators']['this'] return { 'total_households': { 'name': 'Households with heads under 18 years old', 'values': {'this': total_households}, }, 'type_of_dwelling_distribution': type_of_dwelling_dist, 'informal': { 'name': 'Child-headed households that are informal dwellings (shacks)', 'values': {'this': percent(informal, total_households)}, 'numerators': {'this': informal}, }, 'annual_income_distribution': income_dist_data, 'median_annual_income': { 'name': 'Average annual child-headed household income', 'values': {'this': median_income}, }, 'head_of_household': { 'gender_distribution': head_gender_dist, 'female': { 'name': 'Child-headed households with women as their head', 'values': {'this': percent(female_heads, total_households)}, 'numerators': {'this': female_heads}, }, }, }
def get_demographics_profile(geo_code, geo_level, session): pop_dist_data, pop_total = get_stat_data( ['population group'], geo_level, geo_code, session) youth_pop_dist_data, youth_pop_total = get_stat_data(['age in completed years'], geo_level, geo_code, session, table_name='youth_gender_age_in_completed_years') youth_gender_data, _ = get_stat_data(['gender'], geo_level, geo_code, session, table_name='youth_gender_population_group') youth_pop_group_data, _ = get_stat_data(['population group'], geo_level, geo_code, session, table_name='youth_gender_population_group') final_data = { 'total_population': { "name": "People", "values": {"this": pop_total} }, 'youth_population_total': { "name": "Youth aged 15-24", "values": {"this": youth_pop_total} }, 'youth_population_perc': { "name": "Of population are youth aged 15-24", "values": {"this": percent(youth_pop_total, pop_total)}, }, 'youth_population_by_year': youth_pop_dist_data, 'youth_population_by_gender': youth_gender_data, 'youth_population_by_pop_group': youth_pop_group_data } geo = geo_data.get_geography(geo_code, geo_level) if geo.square_kms: final_data['population_density'] = { 'name': "people per square kilometre", 'values': {"this": pop_total / geo.square_kms} } return final_data
def cap_budget_diff(self): values = [] for year in self.years: try: cap_ex_budget = self.results['cap_exp_budget']['4100'][year] cap_ex_actual = self.results['cap_exp_actual']['4100'][year] result = percent((cap_ex_actual - cap_ex_budget), cap_ex_budget) overunder = 'under' if result < 0 else 'over' if abs(result) < 10: rating = 'good' elif abs(result) <= 30: rating = 'ave' elif abs(result) > 30: rating = 'bad' else: rating = None except KeyError: result = None rating = None overunder = None values.append({ 'year': year, 'result': result, 'overunder': overunder, 'rating': rating }) return values
def wasteful_exp_perc_exp(self): values = [] aggregate = {} for item, results in self.results['wasteful_exp'].iteritems(): for year, amount in results.iteritems(): if year in aggregate: aggregate[year] += amount else: aggregate[year] = amount for year in self.years: try: op_ex_actual = self.results['op_exp_actual']['4600'][year] result = percent(aggregate[year], op_ex_actual) rating = None if result == 0: rating = 'good' else: rating = 'bad' except KeyError: result = None rating = None values.append({'year': year, 'result': result, 'rating': rating}) return values
def expenditure_functional_breakdown(self): GAPD_categories = { 'Budget & Treasury Office', 'Executive & Council', 'Planning and Development', 'Corporate Services', } GAPD_label = 'Governance, Administration, Planning and Development' results = self.results['expenditure_functional_breakdown'] grouped_results = [] for year, yeargroup in groupby(results, lambda r: r['financial_year_end.year']): try: total = self.results['expenditure_breakdown']['4600'][year] GAPD_total = 0.0 year_name = year if year != self.budget_year else ("%s budget" % year) for result in yeargroup: # only do budget for budget year, use auda for others if self.check_budget_actual(year, result['amount_type.code']): if result['function.category_label'] in GAPD_categories: GAPD_total += (result['amount.sum'] or 0) else: grouped_results.append({ 'amount': result['amount.sum'] or 0, 'percent': percent((result['amount.sum'] or 0), total), 'item': result['function.category_label'], 'year': year_name, }) grouped_results.append({ 'amount': GAPD_total, 'percent': percent(GAPD_total, total), 'item': GAPD_label, 'year': year_name, }) except KeyError: continue return sorted(grouped_results, key=lambda r: (r['year'], r['item']))
def expenditure_trends(self): values = defaultdict(list) for year in self.years: try: total = self.results['expenditure_breakdown']['4600'][year] except KeyError: total = None try: staff = percent(self.results['expenditure_breakdown']['3000'][year] + self.results['expenditure_breakdown']['3100'][year], total) except KeyError: staff = None try: contracting = percent(self.results['expenditure_breakdown']['4200'][year], total) except KeyError: contracting = None values['staff'].append({'year': year, 'result': staff}) values['contracting'].append({'year': year, 'result': contracting}) return values
def get_economics_profile(geo_code, geo_level, session): # income income_dist_data, total_workers = get_stat_data( ['employed individual monthly income'], geo_level, geo_code, session, exclude=['Not applicable'], recode=COLLAPSED_INCOME_CATEGORIES, key_order=COLLAPSED_INCOME_CATEGORIES.values()) # median income median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_INCOME_CATEGORIES[median] # employment status employ_status, total_workers = get_stat_data( ['official employment status'], geo_level, geo_code, session, exclude=['Age less than 15 years', 'Not applicable'], order_by='official employment status', table_name='officialemploymentstatus') # sector sector_dist_data, _ = get_stat_data( ['type of sector'], geo_level, geo_code, session, exclude=['Not applicable'], order_by='type of sector') # access to internet internet_access_dist, total_with_access = get_stat_data( ['access to internet'], geo_level, geo_code, session, exclude=['No access to internet'], order_by='access to internet') _, total_without_access = get_stat_data( ['access to internet'], geo_level, geo_code, session, only=['No access to internet']) total_households = total_with_access + total_without_access return {'individual_income_distribution': income_dist_data, 'median_individual_income': { 'name': 'Average monthly income', 'values': {'this': median_income}, }, 'employment_status': employ_status, 'sector_type_distribution': sector_dist_data, 'internet_access_distribution': internet_access_dist, 'internet_access': { 'name': 'Households with internet access', 'values': {'this': percent(total_with_access, total_households)}, 'numerators': {'this': total_with_access}, } }
def get_education_profile(geo_code, geo_level, session): youth_completed_grade9, _ = get_stat_data(['completed grade9'], geo_level, geo_code, session, table_name='youth_age_16_to_17_gender_completed_grade9') youth_gender_completed_grade9, _ = get_stat_data(['gender', 'completed grade9'], geo_level, geo_code, session, table_name='youth_age_16_to_17_gender_completed_grade9') db_model_gender_completed_grade9 = get_model_from_fields(['gender'], geo_level, table_name='youth_age_16_to_17_gender_completed_grade9') gender_completed_grade9_data = OrderedDict(( # census data refers to sex as gender ('Female', { "name": "Female", "values": {"this": youth_gender_completed_grade9['Female']['Yes']['values']['this']}, "numerators": {"this": youth_gender_completed_grade9['Female']['Yes']['numerators']['this']}, }), ('Male', { "name": "Male", "values": {"this": youth_gender_completed_grade9['Male']['Yes']['values']['this']}, "numerators": {"this": youth_gender_completed_grade9['Male']['Yes']['numerators']['this']}, }), )) add_metadata(gender_completed_grade9_data, db_model_gender_completed_grade9) youth_education_level, youth_pop_20_to_24 = get_stat_data(['education level'], geo_level, geo_code, session, table_name='youth_age_20_to_24_gender_education_level') matric_or_equiv = ( youth_education_level['Matric']['numerators']['this'] + youth_education_level['Tertiary']['numerators']['this'] + youth_education_level['Some secondary']['numerators']['this']) final_data = { 'youth_completed_grade9': youth_completed_grade9, 'youth_perc_completed_grade9': { "name": "Of youth aged 16-17 have completed grade 9", "values": {"this": youth_completed_grade9['Yes']['values']['this']}, }, 'youth_gender_completed_grade9': gender_completed_grade9_data, 'youth_perc_matric': { "name": "Of youth aged 20-24 have completed matric or matric equivalent", "values": {"this": percent(matric_or_equiv, youth_pop_20_to_24)}, }, 'youth_education_level': youth_education_level } return final_data
def rep_maint_perc_ppe(self): values = [] for year in self.years: try: rep_maint = self.results['rep_maint']['5005'][year] ppe = self.results['ppe']['1300'][year] invest_prop = self.results['invest_prop']['1401'][year] result = percent(rep_maint, (ppe + invest_prop)) if abs(result) >= 8: rating = 'good' elif abs(result) < 8: rating = 'bad' else: rating = None except KeyError: result = None rating = None values.append({'year': year, 'result': result, 'rating': rating}) return values
def get_households_profile(geo, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ['gender of household head'], geo, session, order_by='gender of household head') female_heads = head_gender_dist['Female']['numerators']['this'] # age db_model_u18 = get_model_from_fields( ['gender of head of household'], geo.geo_level, table_name='genderofheadofhouseholdunder18' ) objects = get_objects_by_geo(db_model_u18, geo, session) total_under_18 = float(sum(o[0] for o in objects)) # tenure tenure_data, _ = get_stat_data( ['tenure status'], geo, session, recode=HOUSEHOLD_OWNERSHIP_RECODE, order_by='tenure status') owned = 0 for key, data in tenure_data.iteritems(): if key.startswith('Owned'): owned += data['numerators']['this'] # annual household income if geo.version == '2011': HOUSEHOLD_INCOME_RECODE = HOUSEHOLD_INCOME_RECODE_2011 else: HOUSEHOLD_INCOME_RECODE = COLLAPSED_ANNUAL_INCOME_CATEGORIES income_dist_data, _ = get_stat_data( ['annual household income'], geo, session, exclude=['Unspecified', 'Not applicable'], recode=HOUSEHOLD_INCOME_RECODE, key_order=HOUSEHOLD_INCOME_RECODE.values(), table_name='annualhouseholdincome_genderofhouseholdhead') # median income median = calculate_median_stat(income_dist_data) median_income = HOUSEHOLD_INCOME_ESTIMATE[median] # type of dwelling type_of_dwelling_dist, _ = get_stat_data( ['type of dwelling'], geo, session, recode=TYPE_OF_DWELLING_RECODE, order_by='-total') informal = type_of_dwelling_dist['Shack']['numerators']['this'] # household goods household_goods, _ = get_stat_data( ['household goods'], geo, session, recode=HOUSEHOLD_GOODS_RECODE, key_order=sorted(HOUSEHOLD_GOODS_RECODE.values())) return {'total_households': { 'name': 'Households', 'values': {'this': total_households}, }, 'owned': { 'name': 'Households fully owned or being paid off', 'values': {'this': percent(owned, total_households)}, 'numerators': {'this': owned}, }, 'type_of_dwelling_distribution': type_of_dwelling_dist, 'informal': { 'name': 'Households that are informal dwellings (shacks)', 'values': {'this': percent(informal, total_households)}, 'numerators': {'this': informal}, }, 'tenure_distribution': tenure_data, 'household_goods': household_goods, 'annual_income_distribution': income_dist_data, 'median_annual_income': { 'name': 'Average annual household income', 'values': {'this': median_income}, }, 'head_of_household': { 'gender_distribution': head_gender_dist, 'female': { 'name': 'Households with women as their head', 'values': {'this': percent(female_heads, total_households)}, 'numerators': {'this': female_heads}, }, 'under_18': { 'name': 'Households with heads under 18 years old', 'values': {'this': total_under_18}, } }, }
def get_demographics_profile(geo, session): # population group pop_dist_data, total_pop = get_stat_data( ['population group'], geo, session, table_dataset='Census 2011') # language language_data, _ = get_stat_data( ['language'], geo, session, order_by='-total') language_most_spoken = language_data[language_data.keys()[0]] # age groups age_dist_data, total_age = get_stat_data( ['age groups in 5 years'], geo, session, table_name='agegroupsin5years', recode=COLLAPSED_AGE_CATEGORIES, key_order=('0-9', '10-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+')) # sex sex_data, _ = get_stat_data( ['gender'], geo, session, table_name='gender') final_data = { 'language_distribution': language_data, 'language_most_spoken': language_most_spoken, 'population_group_distribution': pop_dist_data, 'age_group_distribution': age_dist_data, 'sex_ratio': sex_data, 'total_population': { "name": "People", "values": {"this": total_pop}, } } if geo.square_kms: final_data['population_density'] = { 'name': "people per square kilometre", 'values': {"this": total_pop / geo.square_kms}, } # median age/age category db_model_age = get_model_from_fields( ['age in completed years'], geo.geo_level, table_name='ageincompletedyears' ) objects = sorted( get_objects_by_geo(db_model_age, geo, session), key=lambda x: int(getattr(x, 'age in completed years')) ) # median age median = calculate_median(objects, 'age in completed years') final_data['median_age'] = { "name": "Median age", "values": {"this": median}, } # age category age_dist, _ = get_stat_data( ['age in completed years'], geo, session, table_name='ageincompletedyearssimplified', key_order=['Under 18', '18 to 64', '65 and over'], recode={'< 18': 'Under 18', '>= 65': '65 and over'}) final_data['age_category_distribution'] = age_dist # citizenship citizenship_dist, _ = get_stat_data( ['citizenship'], geo, session, order_by='-total') sa_citizen = citizenship_dist['Yes']['numerators']['this'] final_data['citizenship_distribution'] = citizenship_dist final_data['citizenship_south_african'] = { 'name': 'South African citizens', 'values': {'this': percent(sa_citizen, total_pop)}, 'numerators': {'this': sa_citizen}, } # migration province_of_birth_dist, _ = get_stat_data( ['province of birth'], geo, session, exclude_zero=True, order_by='-total') final_data['province_of_birth_distribution'] = province_of_birth_dist def region_recode(field, key): if key == 'Born in South Africa': return 'South Africa' else: return { 'Not applicable': 'Other', }.get(key, key) region_of_birth_dist, _ = get_stat_data( ['region of birth'], geo, session, exclude_zero=True, order_by='-total', recode=region_recode) if 'South Africa' in region_of_birth_dist: born_in_sa = region_of_birth_dist['South Africa']['numerators']['this'] else: born_in_sa = 0 final_data['region_of_birth_distribution'] = region_of_birth_dist final_data['born_in_south_africa'] = { 'name': 'Born in South Africa', 'values': {'this': percent(born_in_sa, total_pop)}, 'numerators': {'this': born_in_sa}, } return final_data
def get_children_profile(geo_code, geo_level, session): # age child_adult_dist, _ = get_stat_data( ['age in completed years'], geo_level, geo_code, session, table_name='ageincompletedyearssimplified', recode={'< 18': 'Children (< 18)', '18 to 64': 'Adults (>= 18)', '>= 65': 'Adults (>= 18)'}) # parental survival survival, total = get_stat_data( ['mother alive', 'father alive'], geo_level, geo_code, session) parental_survival_dist = OrderedDict() parental_survival_dist['metadata'] = survival['metadata'] parental_survival_dist['Both parents'] = survival['Yes']['Yes'] parental_survival_dist['Both parents']['name'] = 'Both parents' parental_survival_dist['Neither parent'] = survival['No']['No'] parental_survival_dist['Neither parent']['name'] = 'Neither parent' parental_survival_dist['One parent'] = survival['Yes']['No'] parental_survival_dist['One parent']['numerators']['this'] += survival['No']['Yes']['numerators']['this'] rest = (total - parental_survival_dist['Both parents']['values']['this'] - parental_survival_dist['Neither parent']['values']['this'] - parental_survival_dist['One parent']['values']['this']) parental_survival_dist['Uncertain'] = { 'name': 'Uncertain', 'numerators': {'this': rest}, } # calculate percentage for data in parental_survival_dist.itervalues(): if 'numerators' in data: data['values'] = {'this': percent(data['numerators']['this'], total)} # gender gender_dist, _ = get_stat_data( ['gender'], geo_level, geo_code, session, table_name='genderunder18') # school # NOTE: this data is incompatible with some views (check out # https://github.com/censusreporter/censusreporter/issues/78) # # school_attendance_dist, total_school_aged = get_stat_data( # ['present school attendance', 'age in completed years'], # geo_level, geo_code, session, # ) # school_attendance_dist['Yes']['metadata'] = \ # school_attendance_dist['metadata'] # school_attendance_dist = school_attendance_dist['Yes'] # total_attendance = sum(d['numerators']['this'] for d in # school_attendance_dist.values() # if 'numerators' in d) # school attendance school_attendance_dist, total_school_aged = get_stat_data( ['present school attendance'], geo_level, geo_code, session, ) total_attendance = school_attendance_dist['Yes']['numerators']['this'] # education level education17_dist, _ = get_stat_data( ['highest educational level'], geo_level, geo_code, session, recode=COLLAPSED_EDUCATION_CATEGORIES, table_name='highesteducationallevel17', key_order=EDUCATION_KEY_ORDER, ) # employment employment_dist, total_15to17 = get_stat_data( ['official employment status'], geo_level, geo_code, session, table_name='officialemploymentstatus15to17', exclude=['Not applicable'] ) total_in_labour_force = float(sum(v["numerators"]["this"] for k, v in employment_dist.iteritems() if COLLAPSED_EMPLOYMENT_CATEGORIES.get(k, None) == 'In labour force')) # median income income_dist_data, total_workers = get_stat_data( ['individual monthly income'], geo_level, geo_code, session, exclude=['Not applicable'], recode=COLLAPSED_INCOME_CATEGORIES, key_order=COLLAPSED_INCOME_CATEGORIES.values(), table_name='individualmonthlyincome15to17' ) median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_INCOME_CATEGORIES[median] return { 'demographics': { 'child_adult_distribution': child_adult_dist, 'total_children': { "name": "Children", "values": {"this": child_adult_dist['Children (< 18)']['numerators']['this']} }, 'gender_distribution': gender_dist, 'parental_survival_distribution': parental_survival_dist, 'percent_no_parent': { "name": "Of children 14 and under have no living biological parents", "values": parental_survival_dist["Neither parent"]['values'], "numerators": parental_survival_dist["Neither parent"]['numerators'], }, }, 'school': { 'school_attendance_distribution': school_attendance_dist, 'percent_school_attendance': { "name": "School-aged children (5 to 17 years old) are in school", "numerators": {"this": total_school_aged}, "values": {"this": percent(float(total_attendance), float(total_school_aged))} }, 'education17_distribution': education17_dist, }, 'employment': { 'percent_in_labour_force': { "name": "Of children between 15 and 17 are in the labour force", "numerators": {"this": total_in_labour_force}, "values": {"this": percent(total_in_labour_force, total_15to17)} }, 'employment_distribution': employment_dist, 'median_income': { 'name': 'Average monthly income of employed children between 15 and 17', 'values': {'this': median_income}, }, } }
def get_profile(geo_code, geo_level, profile_name=None): api_query_strings = { 'aggregate': '{cube}/aggregate?aggregates={aggregate}&cut={cut}&drilldown=item.code|item.label|financial_period.period&page=0', 'facts': '{cube}/facts?&cut={cut}&drilldown=item.code|item.label|financial_period.period&page=0', } line_items = { 'op_exp_actual': { 'cube': 'incexp', 'aggregate': 'amount.sum', 'cut': { 'item.code': '4600', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year', }, 'query_type': 'aggregate', }, 'op_exp_budget': { 'cube': 'incexp', 'aggregate': 'amount.sum', 'cut': { 'item.code': '4600', 'amount_type.label': 'Adjusted Budget', 'demarcation.code': str(geo_code), }, 'query_type': 'aggregate', }, 'cash_flow': { 'cube': 'cflow', 'aggregate': 'amount.sum', 'cut': { 'item.code': '4200', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year' }, 'query_type': 'aggregate', }, 'cap_exp_actual': { 'cube': 'capital', 'aggregate': 'asset_register_summary.sum', 'cut': { 'item.code': '4100', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year' }, 'query_type': 'aggregate', }, 'cap_exp_budget': { 'cube': 'capital', 'aggregate': 'asset_register_summary.sum', 'cut': { 'item.code': '4100', 'amount_type.label': 'Adjusted Budget', 'demarcation.code': str(geo_code), }, 'query_type': 'aggregate', }, 'rep_maint': { 'cube': 'repmaint', 'aggregate': 'amount.sum', 'cut': { 'item.code': '5005', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year' }, 'query_type': 'aggregate', }, 'ppe': { 'cube': 'bsheet', 'aggregate': 'amount.sum', 'cut': { 'item.code': '1300', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year', }, 'query_type': 'aggregate', }, 'invest_prop': { 'cube': 'bsheet', 'aggregate': 'amount.sum', 'cut': { 'item.code': '1401', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year', }, 'query_type': 'aggregate', }, 'officials': { 'cube': 'officials', 'facts': '', 'cut': { 'municipality.demarcation_code': str(geo_code), }, 'query_type': 'facts', }, 'contact_details' : { 'cube': 'municipalities', 'facts': '', 'cut': { 'municipality.demarcation_code': str(geo_code), }, 'query_type': 'facts', } } api_response = {} results = defaultdict(dict) for item, params in line_items.iteritems(): if params['query_type'] == 'aggregate': url = API_URL + api_query_strings['aggregate'].format( aggregate=params['aggregate'], cube=params['cube'], cut='|'.join('{!s}:{!r}'.format(k, v) for (k, v) in params['cut'].iteritems()).replace("'", '"') ) elif params['query_type'] == 'facts': url = API_URL + api_query_strings['facts'].format( facts=params['facts'], cube=params['cube'], cut='|'.join('{!s}:{!r}'.format(k, v) for (k, v) in params['cut'].iteritems()).replace("'", '"') ) api_response[item] = requests.get(url, verify=False).json() if params['query_type'] == 'facts': results[item] = facts_from_response(item, api_response, line_items) else: for year in YEARS: results[item][year] = aggregate_from_response(item, year, api_response, line_items) cash_coverage = {} op_budget_diff = {} cap_budget_diff = {} rep_maint_perc_ppe = {} for year in YEARS: cash_coverage[year] = ratio( results['cash_flow'][year], (results['op_exp_actual'][year] / 12), 1) op_budget_diff[year] = percent( (results['op_exp_budget'][year] - results['op_exp_actual'][year]), results['op_exp_budget'][year], 1) cap_budget_diff[year] = percent( (results['cap_exp_budget'][year] - results['cap_exp_actual'][year]), results['cap_exp_budget'][year]) rep_maint_perc_ppe[year] = percent(results['rep_maint'][year], (results['ppe'][year] + results['invest_prop'][year])) mayoral_staff = [] exclude_roles = ['Speaker', 'Secretary of Speaker'] for official in results['officials']: if not official['role.role'] in exclude_roles: mayoral_staff.append({ 'role': official['role.role'], 'title': official['contact_details.title'], 'name': official['contact_details.name'], 'office_phone': official['contact_details.phone_number'], 'fax_number': official['contact_details.fax_number'], 'email': official['contact_details.email_address'] }) muni_contact = results['contact_details'][0] contact_details = { 'street_address_1': muni_contact['municipality.street_address_1'], 'street_address_2': muni_contact['municipality.street_address_2'], 'street_address_3': muni_contact['municipality.street_address_3'], 'street_address_4': muni_contact['municipality.street_address_4'], 'postal_address_1': muni_contact['municipality.postal_address_1'], 'postal_address_2': muni_contact['municipality.postal_address_2'], 'postal_address_3': muni_contact['municipality.postal_address_3'], 'phone_number': muni_contact['municipality.phone_number'], 'url': muni_contact['municipality.url'].lower() } return { 'cash_coverage': cash_coverage, 'op_budget_diff': op_budget_diff, 'cap_budget_diff': cap_budget_diff, 'rep_maint_perc_ppe': rep_maint_perc_ppe, 'mayoral_staff': mayoral_staff, 'contact_details': contact_details}
def get_economics_profile(geo, session): profile = {} # income if geo.version == "2011": # distribution recode = COLLAPSED_MONTHLY_INCOME_CATEGORIES fields = ["employed individual monthly income"] income_dist_data, total_workers = get_stat_data( fields, geo, session, exclude=["Not applicable"], recode=recode, key_order=recode.values(), ) # median income median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_MONTHLY_INCOME_CATEGORIES[median] profile.update( { "individual_income_distribution": income_dist_data, "median_individual_income": { "name": "Average monthly income", "values": {"this": median_income}, }, } ) else: # distribution recode = COLLAPSED_ANNUAL_INCOME_CATEGORIES fields = ["employed individual annual income"] income_dist_data, total_workers = get_stat_data( fields, geo, session, exclude=["Not applicable"], recode=recode, key_order=recode.values(), ) # median income median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_ANNUAL_INCOME_CATEGORIES[median] profile.update( { "individual_annual_income_distribution": income_dist_data, "median_annual_individual_income": { "name": "Average annual income", "values": {"this": median_income}, }, } ) # employment status employ_status, total_workers = get_stat_data( ["official employment status"], geo, session, exclude=["Age less than 15 years", "Not applicable"], order_by="official employment status", table_name="officialemploymentstatus", ) # sector sector_dist_data, _ = get_stat_data( ["type of sector"], geo, session, exclude=["Not applicable"], order_by="type of sector", ) profile.update( { "employment_status": employ_status, "sector_type_distribution": sector_dist_data, } ) # access to internet if current_context().get("year") == "latest": internet_access_dist, total_households = get_stat_data( ["access to internet"], geo, session, recode=INTERNET_ACCESS_RECODE, table_name="accesstointernet_2016", ) profile.update({"internet_access_distribution": internet_access_dist}) else: internet_access_dist, total_with_access = get_stat_data( ["access to internet"], geo, session, exclude=["No access to internet"], order_by="access to internet", ) _, total_without_access = get_stat_data( ["access to internet"], geo, session, only=["No access to internet"] ) total_households = total_with_access + total_without_access profile.update( { "internet_access_distribution": internet_access_dist, "internet_access": { "name": "Households with internet access", "values": {"this": percent(total_with_access, total_households)}, "numerators": {"this": total_with_access}, }, } ) return profile
def get_profile(geo_code, geo_level, profile_name=None): api_query_strings = { 'aggregate': '{cube}/aggregate?aggregates={aggregate}&cut={cut}&drilldown=item.code|item.label|financial_period.period&page=0&order=financial_period.period:desc', 'facts': '{cube}/facts?&cut={cut}&fields={fields}&page=0', } # Census data table = get_datatable('population_2011') _, total_pop = table.get_stat_data(geo_level, geo_code, percent=False) line_items = { 'op_exp_actual': { 'cube': 'incexp', 'aggregate': 'amount.sum', 'cut': { 'item.code': '4600', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year', }, 'query_type': 'aggregate', }, 'op_exp_budget': { 'cube': 'incexp', 'aggregate': 'amount.sum', 'cut': { 'item.code': '4600', 'amount_type.label': 'Adjusted Budget', 'demarcation.code': str(geo_code), }, 'query_type': 'aggregate', }, 'cash_flow': { 'cube': 'cflow', 'aggregate': 'amount.sum', 'cut': { 'item.code': '4200', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year' }, 'query_type': 'aggregate', }, 'cap_exp_actual': { 'cube': 'capital', 'aggregate': 'asset_register_summary.sum', 'cut': { 'item.code': '4100', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year' }, 'query_type': 'aggregate', }, 'cap_exp_budget': { 'cube': 'capital', 'aggregate': 'asset_register_summary.sum', 'cut': { 'item.code': '4100', 'amount_type.label': 'Adjusted Budget', 'demarcation.code': str(geo_code), }, 'query_type': 'aggregate', }, 'rep_maint': { 'cube': 'repmaint', 'aggregate': 'amount.sum', 'cut': { 'item.code': '5005', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year' }, 'query_type': 'aggregate', }, 'ppe': { 'cube': 'bsheet', 'aggregate': 'amount.sum', 'cut': { 'item.code': '1300', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year', }, 'query_type': 'aggregate', }, 'invest_prop': { 'cube': 'bsheet', 'aggregate': 'amount.sum', 'cut': { 'item.code': '1401', 'amount_type.label': 'Audited Actual', 'demarcation.code': str(geo_code), 'period_length.length': 'year', }, 'query_type': 'aggregate', }, 'officials': { 'query_type': 'facts', 'cube': 'officials', 'cut': { 'municipality.demarcation_code': str(geo_code), }, 'fields': [ 'role.role', 'contact_details.title', 'contact_details.name', 'contact_details.email_address', 'contact_details.phone_number', 'contact_details.fax_number'], 'annual': False, 'value_label': '' }, 'contact_details' : { 'query_type': 'facts', 'cube': 'municipalities', 'cut': { 'municipality.demarcation_code': str(geo_code), }, 'fields': [ 'municipality.phone_number', 'municipality.street_address_1', 'municipality.street_address_2', 'municipality.street_address_3', 'municipality.street_address_4', 'municipality.url' ], 'annual': False, 'value_label': '' }, 'audit_opinions' : { 'query_type': 'facts', 'cube': 'audit_opinions', 'cut': { 'municipality.demarcation_code': str(geo_code), }, 'fields': [ 'opinion.code', 'opinion.label', 'financial_year_end.year' ], 'annual': True, 'value_label': 'opinion.label' } } api_response = {} results = defaultdict(dict) years = set() for item, params in line_items.iteritems(): if params['query_type'] == 'aggregate': url = API_URL + api_query_strings['aggregate'].format( aggregate=params['aggregate'], cube=params['cube'], cut='|'.join('{!s}:{!r}'.format(k, v) for (k, v) in params['cut'].iteritems()).replace("'", '"') ) elif params['query_type'] == 'facts': url = API_URL + api_query_strings['facts'].format( cube=params['cube'], cut='|'.join('{!s}:{!r}'.format(k, v) for (k, v) in params['cut'].iteritems()).replace("'", '"'), fields=','.join(field for field in params['fields']) ) api_response[item] = requests.get(url, verify=False).json() if params['query_type'] == 'facts': if params['annual']: results[item], years = annual_facts_from_response(item, api_response, line_items, years) else: results[item] = facts_from_response(item, api_response, line_items) else: results[item], years = aggregate_from_response(item, api_response, line_items, years) cash_coverage = OrderedDict() op_budget_diff = OrderedDict() cap_budget_diff = OrderedDict() rep_maint_perc_ppe = OrderedDict() for year in sorted(list(years), reverse=True): try: cash_coverage[year] = ratio( results['cash_flow'][year], (results['op_exp_actual'][year] / 12), 1) except KeyError: cash_coverage[year] = None try: op_budget_diff[year] = percent( (results['op_exp_budget'][year] - results['op_exp_actual'][year]), results['op_exp_budget'][year], 1) except KeyError: op_budget_diff[year] = None try: cap_budget_diff[year] = percent( (results['cap_exp_budget'][year] - results['cap_exp_actual'][year]), results['cap_exp_budget'][year]) except KeyError: cap_budget_diff[year] = None try: rep_maint_perc_ppe[year] = percent(results['rep_maint'][year], (results['ppe'][year] + results['invest_prop'][year])) except KeyError: rep_maint_perc_ppe[year] = None cash_at_year_end = OrderedDict([ (k, v) for k, v in results['cash_flow'].iteritems() ]) mayoral_staff = [] exclude_roles = ['Speaker', 'Secretary of Speaker'] for official in results['officials']: if not official['role.role'] in exclude_roles: mayoral_staff.append({ 'role': official['role.role'], 'title': official['contact_details.title'], 'name': official['contact_details.name'], 'office_phone': official['contact_details.phone_number'], 'fax_number': official['contact_details.fax_number'], 'email': official['contact_details.email_address'] }) muni_contact = results['contact_details'][0] contact_details = { 'street_address_1': muni_contact['municipality.street_address_1'], 'street_address_2': muni_contact['municipality.street_address_2'], 'street_address_3': muni_contact['municipality.street_address_3'], 'street_address_4': muni_contact['municipality.street_address_4'], 'phone_number': muni_contact['municipality.phone_number'], 'url': muni_contact['municipality.url'].lower() } audit_opinions = OrderedDict(sorted(results['audit_opinions'].items(), key=lambda t: t[0], reverse=True)) return { 'total_population': total_pop, 'cash_coverage': cash_coverage, 'op_budget_diff': op_budget_diff, 'cap_budget_diff': cap_budget_diff, 'rep_maint_perc_ppe': rep_maint_perc_ppe, 'mayoral_staff': mayoral_staff, 'contact_details': contact_details, 'audit_opinions': audit_opinions, 'cash_at_year_end': cash_at_year_end}
def set_percent_values(data, total): for fields in data.values(): fields["values"] = {"this": percent(fields["numerators"]["this"], total)}
def get_child_households_profile(geo, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ["gender of head of household"], geo, session, table_universe="Households headed by children under 18", order_by="gender of head of household", ) female_heads = head_gender_dist["Female"]["numerators"]["this"] # annual household income if geo.version == "2011": HOUSEHOLD_INCOME_RECODE = HOUSEHOLD_INCOME_RECODE_2011 else: HOUSEHOLD_INCOME_RECODE = COLLAPSED_ANNUAL_INCOME_CATEGORIES income_dist_data, _ = get_stat_data( ["annual household income"], geo, session, exclude=["Unspecified"], recode=HOUSEHOLD_INCOME_RECODE, key_order=HOUSEHOLD_INCOME_RECODE.values(), table_name="annualhouseholdincomeunder18", ) # median income median = calculate_median_stat(income_dist_data) median_income = HOUSEHOLD_INCOME_ESTIMATE[median] # type of dwelling type_of_dwelling_dist, _ = get_stat_data( ["type of main dwelling"], geo, session, recode=TYPE_OF_DWELLING_RECODE, order_by="-total", ) informal = type_of_dwelling_dist["Shack"]["numerators"]["this"] return { "total_households": { "name": "Households with heads under 18 years old", "values": {"this": total_households}, }, "type_of_dwelling_distribution": type_of_dwelling_dist, "informal": { "name": "Child-headed households that are informal dwellings (shacks)", "values": {"this": percent(informal, total_households)}, "numerators": {"this": informal}, }, "annual_income_distribution": income_dist_data, "median_annual_income": { "name": "Average annual child-headed household income", "values": {"this": median_income}, }, "head_of_household": { "gender_distribution": head_gender_dist, "female": { "name": "Child-headed households with women as their head", "values": {"this": percent(female_heads, total_households)}, "numerators": {"this": female_heads}, }, }, }
def get_demographics_profile(geo_code, geo_level, session): # population group pop_dist_data, total_pop = get_stat_data( ['population group'], geo_level, geo_code, session) # language language_data, _ = get_stat_data( ['language'], geo_level, geo_code, session, order_by='-total') language_most_spoken = language_data[language_data.keys()[0]] # age groups age_dist_data, total_age = get_stat_data( ['age groups in 5 years'], geo_level, geo_code, session, table_name='agegroupsin5years', recode=COLLAPSED_AGE_CATEGORIES, key_order=('0-9', '10-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80+')) # sex db_model_sex = get_model_from_fields(['gender'], geo_level, table_name='gender') query = session.query(func.sum(db_model_sex.total)) \ .filter(db_model_sex.gender == 'Male') query = query.filter(db_model_sex.geo_code == geo_code) total_male = query.one()[0] sex_data = OrderedDict(( # census data refers to sex as gender ('Female', { "name": "Female", "values": {"this": round((total_pop - total_male) / total_pop * 100, 2)}, "numerators": {"this": total_pop - total_male}, }), ('Male', { "name": "Male", "values": {"this": round(total_male / total_pop * 100, 2)}, "numerators": {"this": total_male}, }), )) add_metadata(sex_data, db_model_sex) final_data = { 'language_distribution': language_data, 'language_most_spoken': language_most_spoken, 'population_group_distribution': pop_dist_data, 'age_group_distribution': age_dist_data, 'sex_ratio': sex_data, 'total_population': { "name": "People", "values": {"this": total_pop}, } } geo = geo_data.get_geography(geo_code, geo_level) if geo.square_kms: final_data['population_density'] = { 'name': "people per square kilometre", 'values': {"this": total_pop / geo.square_kms}, } # median age/age category db_model_age = get_model_from_fields( ['age in completed years'], geo_level, table_name='ageincompletedyears' ) objects = sorted( get_objects_by_geo(db_model_age, geo_code, geo_level, session), key=lambda x: int(getattr(x, 'age in completed years')) ) # median age median = calculate_median(objects, 'age in completed years') final_data['median_age'] = { "name": "Median age", "values": {"this": median}, } # age category age_dist, _ = get_stat_data( ['age in completed years'], geo_level, geo_code, session, table_name='ageincompletedyearssimplified', key_order=['Under 18', '18 to 64', '65 and over'], recode={'< 18': 'Under 18', '>= 65': '65 and over'}) final_data['age_category_distribution'] = age_dist # citizenship citizenship_dist, _ = get_stat_data( ['citizenship'], geo_level, geo_code, session, order_by='-total') sa_citizen = citizenship_dist['Yes']['numerators']['this'] final_data['citizenship_distribution'] = citizenship_dist final_data['citizenship_south_african'] = { 'name': 'South African citizens', 'values': {'this': percent(sa_citizen, total_pop)}, 'numerators': {'this': sa_citizen}, } # migration province_of_birth_dist, _ = get_stat_data( ['province of birth'], geo_level, geo_code, session, exclude_zero=True, order_by='-total') final_data['province_of_birth_distribution'] = province_of_birth_dist def region_recode(field, key): if key == 'Born in South Africa': return 'South Africa' else: return key region_of_birth_dist, _ = get_stat_data( ['region of birth'], geo_level, geo_code, session, exclude_zero=True, order_by='-total', recode=region_recode) if 'South Africa' in region_of_birth_dist: born_in_sa = region_of_birth_dist['South Africa']['numerators']['this'] else: born_in_sa = 0 final_data['region_of_birth_distribution'] = region_of_birth_dist final_data['born_in_south_africa'] = { 'name': 'Born in South Africa', 'values': {'this': percent(born_in_sa, total_pop)}, 'numerators': {'this': born_in_sa}, } return final_data
def get_education_profile(geo, session, display_profile, comparative=False): youth_completed_grade9, _ = get_stat_data( ['completed grade9'], geo, session, table_universe='Youth aged 16 to 17', table_dataset='Census and Community Survey', key_order=('Completed', 'Not completed')) youth_completed_grade9_by_gender, _ = get_stat_data( ['completed grade9', 'gender'], geo, session, table_universe='Youth aged 16 to 17', table_dataset='Census and Community Survey', percent_grouping=['gender'], slices=['Completed'], key_order={'gender': GENDER_ORDER}) youth_education_level, youth_pop_20_to_24 = get_stat_data( ['education level'], geo, session, table_universe='Youth aged 20 to 24', table_dataset='Census and Community Survey', key_order=EDUCATION_LEVEL_KEY_ORDER) youth_perc_matric = None if youth_education_level['Matric/matric equivalent']['numerators']['this']: matric_or_equiv = ( youth_education_level['Matric/matric equivalent']['numerators'] ['this'] + youth_education_level['Any tertiary']['numerators']['this']) youth_perc_matric = percent(matric_or_equiv, youth_pop_20_to_24) youth_education_attendance, _ = get_stat_data( ['attendance'], geo, session, table_universe='Youth', table_dataset='Census and Community Survey', table_fields=['attendance', 'age in completed years', 'gender']) youth_education_attending_by_age, _ = get_stat_data( ['attendance', 'age in completed years'], geo, session, table_universe='Youth', table_dataset='Census and Community Survey', table_fields=['attendance', 'age in completed years', 'gender'], table_name='youth_education_attendance_age_incompleted_years_gender', percent_grouping=['age in completed years'], slices=['Yes']) youth_education_attending_by_gender, _ = get_stat_data( ['attendance', 'gender'], geo, session, table_universe='Youth', table_dataset='Census and Community Survey', table_fields=['attendance', 'age in completed years', 'gender'], percent_grouping=['gender'], slices=['Yes'], key_order={'gender': GENDER_ORDER}) final_data = { 'youth_completed_grade9': youth_completed_grade9, 'youth_perc_completed_grade9': { 'name': 'Of youth aged 16-17 have completed grade 9 or higher', 'values': { 'this': youth_completed_grade9['Completed']['values']['this'] } }, 'youth_completed_grade9_by_gender': youth_completed_grade9_by_gender, 'youth_education_level': youth_education_level, 'youth_perc_matric': { "name": "Of youth aged 20-24 have completed matric/matric equivalent or higher", "values": { "this": youth_perc_matric } }, 'youth_perc_attending': { "name": "Of youth aged 15-24 attend an educational institution", "values": { "this": youth_education_attendance['Yes']['values']['this'] } }, 'youth_education_attending_by_age': youth_education_attending_by_age, 'youth_education_attending_by_gender': youth_education_attending_by_gender, } if display_profile == 'WC': with dataset_context(year='2017'): youth_average_mean_score_by_year, _ = get_stat_data( ['year'], geo, session, table_universe= 'Average mean score in both language and mathematics', percent=False) youth_average_language_score_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Average score in language', percent=False) youth_average_maths_score_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Average score in mathematics', percent=False) youth_language_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Percentage passed in language', key_order={'outcome': ['Passed', 'Failed']}, percent=False, slices=['2017']) youth_maths_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Percentage passed in mathematics', key_order={'outcome': ['Passed', 'Failed']}, percent=False, slices=['2017']) with dataset_context(year='2017'): youth_matric_outcome_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Matric pass rate', only={'outcome': ['Passed']}, percent=False) youth_matric_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Matric pass rate', key_order={'outcome': ['Passed', 'Failed']}, percent=False, slices=['2017']) youth_matric_throughput_rate_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Matric passes as a % of grade 8 enrolment', only={'outcome': ['Passed']}, percent=False) youth_matric_throughput_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Matric passes as a % of grade 8 enrolment', key_order={'outcome': ['Passed', 'Dropped out or failed']}, percent=False, slices=['2017']) youth_bachelor_passes_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Bachelor passes as a % of grade 8 enrolment', only={'outcome': ['Bachelor pass']}, percent=False) youth_bachelor_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Bachelor passes as a % of grade 8 enrolment', key_order={'outcome': ['Bachelor pass', 'No bachelor pass']}, percent=False, slices=['2017']) youth_student_dropout_rate_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Dropout rates between grade 10 and matric', only={'outcome': ['Dropped out']}, percent=False) youth_student_dropout_rate_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Dropout rates between grade 10 and matric', percent=False, slices=['2017']) final_data.update({ 'youth_ave_mean_score_latest': { "name": "Average mean score in both language and mathematics", "values": { "this": youth_average_mean_score_by_year['2017']['values']['this'] } }, 'youth_ave_mean_score_by_year': youth_average_mean_score_by_year, 'youth_ave_language_score_latest': { "name": "Average score in language", "values": { "this": youth_average_language_score_by_year['2017']['values'] ['this'] } }, 'youth_ave_language_score_by_year': youth_average_language_score_by_year, 'youth_ave_maths_score_latest': { "name": "Average score in mathematics", "values": { "this": youth_average_maths_score_by_year['2017']['values']['this'] } }, 'youth_ave_maths_score_by_year': youth_average_maths_score_by_year, 'youth_language_outcome_latest': youth_language_outcome_latest, 'youth_maths_outcome_latest': youth_maths_outcome_latest, 'youth_matric_pass_rate_latest': { "name": "Of students writing matric passed", "values": { "this": youth_matric_outcome_latest['Passed']['values']['this'] } }, 'youth_matric_outcome_latest': youth_matric_outcome_latest, 'youth_matric_outcome_by_year': youth_matric_outcome_by_year, 'youth_matric_throughput_rate_latest': { "name": "Of Grade 8 students go on to pass matric", "values": { "this": youth_matric_throughput_latest['Passed']['values']['this'] } }, 'youth_matric_throughput_latest': youth_matric_throughput_latest, 'youth_matric_throughput_rate_by_year': youth_matric_throughput_rate_by_year, 'youth_bachelor_passes_latest': { "name": "Of Grade 8 students go on to pass matric with a bachelor's pass", "values": { "this": youth_bachelor_outcome_latest['Bachelor pass']['values'] ['this'] } }, 'youth_bachelor_outcome_latest': youth_bachelor_outcome_latest, 'youth_bachelor_passes_by_year': youth_bachelor_passes_by_year, 'youth_student_dropout_rate_latest': { "name": "Of students drop out between grade 10 and matric", "values": { "this": youth_student_dropout_rate_latest['Dropped out']['values'] ['this'] } }, 'youth_student_dropout_rate_by_year': youth_student_dropout_rate_by_year }) return final_data
def get_households_profile(geo_code, geo_level, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ['gender of household head'], geo_level, geo_code, session, order_by='gender of household head') female_heads = head_gender_dist['Female']['numerators']['this'] # age db_model_u18 = get_model_from_fields( ['gender of head of household'], geo_level, table_name='genderofheadofhouseholdunder18' ) objects = get_objects_by_geo(db_model_u18, geo_code, geo_level, session) total_under_18 = float(sum(o[0] for o in objects)) # tenure tenure_data, _ = get_stat_data( ['tenure status'], geo_level, geo_code, session, order_by='tenure status') owned = 0 for key, data in tenure_data.iteritems(): if key.startswith('Owned'): owned += data['numerators']['this'] # annual household income income_dist_data, _ = get_stat_data( ['annual household income'], geo_level, geo_code, session, exclude=['Unspecified'], recode=HOUSEHOLD_INCOME_RECODE, key_order=HOUSEHOLD_INCOME_RECODE.values(), table_name='annualhouseholdincome_genderofhouseholdhead') # median income median = calculate_median_stat(income_dist_data) median_income = HOUSEHOLD_INCOME_ESTIMATE[median] # type of dwelling type_of_dwelling_dist, _ = get_stat_data( ['type of dwelling'], geo_level, geo_code, session, recode=TYPE_OF_DWELLING_RECODE, order_by='-total') informal = type_of_dwelling_dist['Shack']['numerators']['this'] # household goods household_goods, _ = get_stat_data( ['household goods'], geo_level, geo_code, session, total=total_households, recode=HOUSEHOLD_GOODS_RECODE, exclude=['total households'], key_order=sorted(HOUSEHOLD_GOODS_RECODE.values())) return {'total_households': { 'name': 'Households', 'values': {'this': total_households}, }, 'owned': { 'name': 'Households fully owned or being paid off', 'values': {'this': percent(owned, total_households)}, 'numerators': {'this': owned}, }, 'type_of_dwelling_distribution': type_of_dwelling_dist, 'informal': { 'name': 'Households that are informal dwellings (shacks)', 'values': {'this': percent(informal, total_households)}, 'numerators': {'this': informal}, }, 'tenure_distribution': tenure_data, 'household_goods': household_goods, 'annual_income_distribution': income_dist_data, 'median_annual_income': { 'name': 'Average annual household income', 'values': {'this': median_income}, }, 'head_of_household': { 'gender_distribution': head_gender_dist, 'female': { 'name': 'Households with women as their head', 'values': {'this': percent(female_heads, total_households)}, 'numerators': {'this': female_heads}, }, 'under_18': { 'name': 'Households with heads under 18 years old', 'values': {'this': total_under_18}, } }, }
def get_economics_profile(geo, session): profile = {} # income if geo.version == '2011': # distribution recode = COLLAPSED_MONTHLY_INCOME_CATEGORIES fields = ['employed individual monthly income'] income_dist_data, total_workers = get_stat_data( fields, geo, session, exclude=['Not applicable'], recode=recode, key_order=recode.values()) # median income median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_MONTHLY_INCOME_CATEGORIES[median] profile.update({ 'individual_income_distribution': income_dist_data, 'median_individual_income': { 'name': 'Average monthly income', 'values': {'this': median_income}, } }) else: # distribution recode = COLLAPSED_ANNUAL_INCOME_CATEGORIES fields = ['employed individual annual income'] income_dist_data, total_workers = get_stat_data( fields, geo, session, exclude=['Not applicable'], recode=recode, key_order=recode.values()) # median income median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_ANNUAL_INCOME_CATEGORIES[median] profile.update({ 'individual_annual_income_distribution': income_dist_data, 'median_annual_individual_income': { 'name': 'Average annual income', 'values': {'this': median_income}, } }) # employment status employ_status, total_workers = get_stat_data( ['official employment status'], geo, session, exclude=['Age less than 15 years', 'Not applicable'], order_by='official employment status', table_name='officialemploymentstatus') # sector sector_dist_data, _ = get_stat_data( ['type of sector'], geo, session, exclude=['Not applicable'], order_by='type of sector') # access to internet internet_access_dist, total_with_access = get_stat_data( ['access to internet'], geo, session, exclude=['No access to internet'], order_by='access to internet') _, total_without_access = get_stat_data( ['access to internet'], geo, session, only=['No access to internet']) total_households = total_with_access + total_without_access profile.update({ 'employment_status': employ_status, 'sector_type_distribution': sector_dist_data, 'internet_access_distribution': internet_access_dist, 'internet_access': { 'name': 'Households with internet access', 'values': {'this': percent(total_with_access, total_households)}, 'numerators': {'this': total_with_access}, } }) return profile
def get_service_delivery_profile(geo, session): # water source water_src_data, total_wsrc = get_stat_data( ['source of water'], geo, session, recode=SHORT_WATER_SOURCE_CATEGORIES, order_by='-total') if 'Service provider' in water_src_data: total_water_sp = water_src_data['Service provider']['numerators']['this'] else: total_water_sp = 0.0 # refuse disposal db_model_ref = get_model_from_fields(['refuse disposal'], geo.geo_level) objects = get_objects_by_geo(db_model_ref, geo, session, order_by='-total') refuse_disp_data = OrderedDict() total_ref = 0.0 total_ref_sp = 0.0 for obj in objects: attr = getattr(obj, 'refuse disposal') disp = SHORT_REFUSE_DISPOSAL_CATEGORIES[attr] refuse_disp_data[disp] = { "name": disp, "numerators": {"this": obj.total}, } total_ref += obj.total if attr.startswith('Removed by local authority'): total_ref_sp += obj.total set_percent_values(refuse_disp_data, total_ref) add_metadata(refuse_disp_data, db_model_ref) # electricity if geo.version == '2011': elec_attrs = ['electricity for cooking', 'electricity for heating', 'electricity for lighting'] db_model_elec = get_model_from_fields(elec_attrs, geo.geo_level) objects = get_objects_by_geo(db_model_elec, geo, session) total_elec = 0.0 total_some_elec = 0.0 elec_access_data = { 'total_all_elec': { "name": "Have electricity for everything", "numerators": {"this": 0.0}, }, 'total_some_not_all_elec': { "name": "Have electricity for some things", "numerators": {"this": 0.0}, }, 'total_no_elec': { "name": "No electricity", "numerators": {"this": 0.0}, } } for obj in objects: total_elec += obj.total has_some = False has_all = True for attr in elec_attrs: val = not getattr(obj, attr).startswith('no ') has_all = has_all and val has_some = has_some or val if has_some: total_some_elec += obj.total if has_all: elec_access_data['total_all_elec']['numerators']['this'] += obj.total elif has_some: elec_access_data['total_some_not_all_elec']['numerators']['this'] += obj.total else: elec_access_data['total_no_elec']['numerators']['this'] += obj.total set_percent_values(elec_access_data, total_elec) add_metadata(elec_access_data, db_model_elec) # toilets toilet_data, total_toilet = get_stat_data( ['toilet facilities'], geo, session, exclude_zero=True, recode=COLLAPSED_TOILET_CATEGORIES, order_by='-total') total_flush_toilet = 0.0 total_no_toilet = 0.0 for key, data in toilet_data.iteritems(): if key.startswith('Flush') or key.startswith('Chemical'): total_flush_toilet += data['numerators']['this'] if key == 'None': total_no_toilet += data['numerators']['this'] profile = { 'water_source_distribution': water_src_data, 'percentage_water_from_service_provider': { "name": "Are getting water from a regional or local service provider", "numerators": {"this": total_water_sp}, "values": {"this": percent(total_water_sp, total_wsrc)}, }, 'refuse_disposal_distribution': refuse_disp_data, 'percentage_ref_disp_from_service_provider': { "name": "Are getting refuse disposal from a local authority or private company", "numerators": {"this": total_ref_sp}, "values": {"this": percent(total_ref_sp, total_ref)}, }, 'percentage_flush_toilet_access': { "name": "Have access to flush or chemical toilets", "numerators": {"this": total_flush_toilet}, "values": {"this": percent(total_flush_toilet, total_toilet)}, }, 'percentage_no_toilet_access': { "name": "Have no access to any toilets", "numerators": {"this": total_no_toilet}, "values": {"this": percent(total_no_toilet, total_toilet)}, }, 'toilet_facilities_distribution': toilet_data, } if geo.version == '2011': profile.update({ 'percentage_electricity_access': { "name": "Have electricity for at least one of cooking, heating or lighting", "numerators": {"this": total_some_elec}, "values": {"this": percent(total_some_elec, total_elec)}, }, 'electricity_access_distribution': elec_access_data, }) return profile
def get_households_profile(geo, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ['gender of household head'], geo, session, order_by='gender of household head') female_heads = head_gender_dist['Female']['numerators']['this'] # age db_model_u18 = get_model_from_fields( ['gender of head of household'], geo.geo_level, table_name='genderofheadofhouseholdunder18') objects = get_objects_by_geo(db_model_u18, geo, session) total_under_18 = float(sum(o[0] for o in objects)) # type of dwelling type_of_dwelling_dist, _ = get_stat_data(['type of dwelling'], geo, session, recode=TYPE_OF_DWELLING_RECODE, order_by='-total') informal = type_of_dwelling_dist['Shack']['numerators']['this'] _, total_ecd_children = get_stat_data(['age in completed years'], geo, session, table_name='ageincompletedyears', only=['0', '1', '2', '3', '4', '5']) ecd_children_per_household = ratio(total_ecd_children, total_households) return { 'total_households': { 'name': 'Households', 'values': { 'this': total_households }, }, 'type_of_dwelling_distribution': type_of_dwelling_dist, 'informal': { 'name': 'Households that are informal dwellings (shacks)', 'values': { 'this': percent(informal, total_households) }, 'numerators': { 'this': informal }, }, 'head_of_household': { 'gender_distribution': head_gender_dist, 'female': { 'name': 'Households with women as their head', 'values': { 'this': percent(female_heads, total_households) }, 'numerators': { 'this': female_heads }, }, 'under_18': { 'name': 'Households with heads under 18 years old', 'values': { 'this': total_under_18 }, } }, 'ecd_children_per_household': { 'name': 'Average number of children (aged 0-5) in each household', 'values': { 'this': ecd_children_per_household }, }, }
def get_children_profile(geo, session): profile = {} # age child_adult_dist, _ = get_stat_data( ['age in completed years'], geo, session, table_name='ageincompletedyearssimplified', recode={'< 18': 'Children (< 18)', '18 to 64': 'Adults (>= 18)', '>= 65': 'Adults (>= 18)'}) # parental survival survival, total = get_stat_data( ['mother alive', 'father alive'], geo, session) parental_survival_dist = OrderedDict() parental_survival_dist['metadata'] = survival['metadata'] parental_survival_dist['Both parents'] = survival['Yes']['Yes'] parental_survival_dist['Both parents']['name'] = 'Both parents' parental_survival_dist['Neither parent'] = survival['No']['No'] parental_survival_dist['Neither parent']['name'] = 'Neither parent' parental_survival_dist['One parent'] = survival['Yes']['No'] parental_survival_dist['One parent']['numerators']['this'] += survival['No']['Yes']['numerators']['this'] rest = (total - parental_survival_dist['Both parents']['values']['this'] - parental_survival_dist['Neither parent']['values']['this'] - parental_survival_dist['One parent']['values']['this']) parental_survival_dist['Uncertain'] = { 'name': 'Uncertain', 'numerators': {'this': rest}, } # calculate percentage for data in parental_survival_dist.itervalues(): if 'numerators' in data: data['values'] = {'this': percent(data['numerators']['this'], total)} # gender gender_dist, _ = get_stat_data( ['gender'], geo, session, table_name='genderunder18') # school # NOTE: this data is incompatible with some views (check out # https://github.com/censusreporter/censusreporter/issues/78) # # school_attendance_dist, total_school_aged = get_stat_data( # ['present school attendance', 'age in completed years'], # geo, session, # ) # school_attendance_dist['Yes']['metadata'] = \ # school_attendance_dist['metadata'] # school_attendance_dist = school_attendance_dist['Yes'] # total_attendance = sum(d['numerators']['this'] for d in # school_attendance_dist.values() # if 'numerators' in d) # school attendance school_attendance_dist, total_school_aged = get_stat_data( ['present school attendance'], geo, session, recode=COLLAPSED_ATTENDANCE_CATEGORIES, ) total_attendance = school_attendance_dist['Yes']['numerators']['this'] # education level education17_dist, _ = get_stat_data( ['highest educational level'], geo, session, recode=COLLAPSED_EDUCATION_CATEGORIES, table_name='highesteducationallevel17', key_order=EDUCATION_KEY_ORDER, ) # employment employment_dist, total_15to17 = get_stat_data( ['official employment status'], geo, session, table_name='officialemploymentstatus15to17', exclude=['Not applicable'] ) total_in_labour_force = float(sum(v["numerators"]["this"] for k, v in employment_dist.iteritems() if COLLAPSED_EMPLOYMENT_CATEGORIES.get(k, None) == 'In labour force')) employment_indicators = { 'percent_in_labour_force': { "name": "Of children between 15 and 17 are in the labour force", "numerators": {"this": total_in_labour_force}, "values": {"this": percent(total_in_labour_force, total_15to17)} }, 'employment_distribution': employment_dist, } # median income if geo.version == '2011': recode = COLLAPSED_MONTHLY_INCOME_CATEGORIES fields = ['individual monthly income'] table_name = 'individualmonthlyincome15to17' income_dist_data, total_workers = get_stat_data( fields, geo, session, exclude=['Not applicable'], recode=recode, key_order=recode.values(), table_name=table_name ) median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_MONTHLY_INCOME_CATEGORIES[median] employment_indicators.update({ 'median_income': { 'name': 'Average monthly income of employed children between 15 and 17', 'values': {'this': median_income}, } }) else: recode = COLLAPSED_ANNUAL_INCOME_CATEGORIES fields = ['individual annual income'] table_name = 'individualannualincome15to17' income_dist_data, total_workers = get_stat_data( fields, geo, session, exclude=['Not applicable'], recode=recode, key_order=recode.values(), table_name=table_name ) median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_ANNUAL_INCOME_CATEGORIES[median] employment_indicators.update({ 'median_annual_income': { 'name': 'Average annual income of employed children between 15 and 17', 'values': {'this': median_income}, } }) profile.update({ 'demographics': { 'child_adult_distribution': child_adult_dist, 'total_children': { "name": "Children", "values": {"this": child_adult_dist['Children (< 18)']['numerators']['this']} }, 'gender_distribution': gender_dist, 'parental_survival_distribution': parental_survival_dist, 'percent_no_parent': { "name": "Of children 14 and under have no living biological parents", "values": parental_survival_dist["Neither parent"]['values'], "numerators": parental_survival_dist["Neither parent"]['numerators'], }, }, 'school': { 'school_attendance_distribution': school_attendance_dist, 'percent_school_attendance': { "name": "School-aged children (5 to 17 years old) are in school", "numerators": {"this": total_school_aged}, "values": {"this": percent(float(total_attendance), float(total_school_aged))} }, 'education17_distribution': education17_dist, }, 'employment': employment_indicators }) return profile
def get_households_profile(geo, session): # head of household # gender head_gender_dist, total_households = get_stat_data( ["gender of household head"], geo, session, table_universe="Households", order_by="gender of household head", ) female_heads = head_gender_dist["Female"]["numerators"]["this"] # age u18_table = get_datatable("genderofheadofhouseholdunder18") objects = u18_table.get_rows_for_geo(geo, session) total_under_18 = float(sum(o[0] for o in objects)) # tenure tenure_data, _ = get_stat_data( ["tenure status"], geo, session, table_universe="Households", recode=HOUSEHOLD_OWNERSHIP_RECODE, order_by="-total", ) owned = 0 for key, data in tenure_data.iteritems(): if key.startswith("Owned"): owned += data["numerators"]["this"] # annual household income if geo.version == "2011": HOUSEHOLD_INCOME_RECODE = HOUSEHOLD_INCOME_RECODE_2011 else: HOUSEHOLD_INCOME_RECODE = COLLAPSED_ANNUAL_INCOME_CATEGORIES income_dist_data, _ = get_stat_data( ["annual household income"], geo, session, table_universe="Households", exclude=["Unspecified", "Not applicable"], recode=HOUSEHOLD_INCOME_RECODE, key_order=HOUSEHOLD_INCOME_RECODE.values(), ) # median income median = calculate_median_stat(income_dist_data) median_income = HOUSEHOLD_INCOME_ESTIMATE[median] # type of dwelling type_of_dwelling_dist, _ = get_stat_data( ["type of dwelling"], geo, session, table_universe="Households", recode=TYPE_OF_DWELLING_RECODE, order_by="-total", ) informal = type_of_dwelling_dist["Shack"]["numerators"]["this"] # household goods household_goods, _ = get_stat_data( ["household goods"], geo, session, table_universe="Households", recode=HOUSEHOLD_GOODS_RECODE, key_order=sorted(HOUSEHOLD_GOODS_RECODE.values()), ) return { "total_households": { "name": "Households", "values": {"this": total_households}, }, "owned": { "name": "Households fully owned or being paid off", "values": {"this": percent(owned, total_households)}, "numerators": {"this": owned}, }, "type_of_dwelling_distribution": type_of_dwelling_dist, "informal": { "name": "Households that are informal dwellings (shacks)", "values": {"this": percent(informal, total_households)}, "numerators": {"this": informal}, }, "tenure_distribution": tenure_data, "household_goods": household_goods, "annual_income_distribution": income_dist_data, "median_annual_income": { "name": "Average annual household income", "values": {"this": median_income}, }, "head_of_household": { "gender_distribution": head_gender_dist, "female": { "name": "Households with women as their head", "values": {"this": percent(female_heads, total_households)}, "numerators": {"this": female_heads}, }, "under_18": { "name": "Households with heads under 18 years old", "values": {"this": total_under_18}, }, }, }
def get_ecd_centres_profile(geo, session): children_age_groups, total_children = get_stat_data( ['age in completed years'], geo, session, table_name='ageincompletedyears', only=['3', '4', '5', '6'], recode=ECD_AGE_CATEGORIES, percent=False, key_order=['0-2', '3-5', '6-7']) children_3_to_5 = children_age_groups['3-5']['values']['this'] # This will not be needed when the column names for centres are changed. reg_recode = { 'registration_incomplete-access_denied': 'Registration incomplete', 'registration_incomplete-closed': 'Registration incomplete', 'registration_incomplete-not_found': 'Registration incomplete', } table = get_datatable('ecd_centres_by_registration') ecd_centres_by_registration, total_ecd_centres = table.get_stat_data( geo, percent=True, recode=reg_recode) table = get_datatable('ecd_children_enrolled') children_enrolled, _ = table.get_stat_data( geo, percent=False) children_enrolled['children_enrolled_age_3_to_5']['name'] = 'Children enrolled in ECD centres' children_3_to_5_coverage = percent( children_enrolled['children_enrolled_age_3_to_5']['values']['this'], children_3_to_5) children_3_to_5_per_ecd_centre = ratio( children_3_to_5, total_ecd_centres) children_3_to_5_per_ecd_centre_enrolled = ratio( children_enrolled['children_enrolled_age_3_to_5']['values']['this'], total_ecd_centres) table = get_datatable('ecd_centres_by_type') ecd_centres_by_type, _ = table.get_stat_data( geo, key_order=['community_based', 'home_based', 'school_based', 'other', 'not_specified']) table = get_datatable('ecd_grade_r') grade_r, _ = table.get_stat_data( geo, percent=False) grade_r['centres_with_grade_r_learners']['name'] = "Centres with Grade R learners" # Currently there's no data available for these datapoints. # They are displayed in the template to promote this fact. registered_ecd_programmes = { "name": "Registered ECD programmes", "values": {"this": None}, } children_in_ecd_programmes = { "name": "Children in programmes", "values": {"this": None}, } children_in_play_groups = { "name": "Children in play groups", "values": {"this": None}, } children_grade_r_age = { "name": "Children of Grade R age (6 years)", "values": {"this": children_age_groups['6']['values']['this']} } schools_with_grade_r_learners = { "name": "Schools with Grade R learners", "values": {"this": None} } return { "total_ecd_centres": { "name": "Number of ECD centres", "values": {"this": total_ecd_centres} }, "ecd_centres_by_registration": ecd_centres_by_registration, "ecd_centres_by_type": ecd_centres_by_type, "registered_ecd_programmes": registered_ecd_programmes, "children_enrolled_age_3_to_5": children_enrolled['children_enrolled_age_3_to_5'], "children_3_to_5_coverage": { "name": "Children living in the area who are enrolled in ECD centres. (Children enrolled in centres / Children living in the area)", "values": {"this": children_3_to_5_coverage} }, "children_3_to_5_per_ecd_centre": { "name": "Average number of children living in the area for each ECD centre", "values": {"this": children_3_to_5_per_ecd_centre} }, "children_3_to_5_per_ecd_centre_enrolled": { "name": "Average number of children enrolled in each ECD centre", "values": {"this": children_3_to_5_per_ecd_centre_enrolled} }, "children_in_ecd_programmes": children_in_ecd_programmes, "children_in_play_groups": children_in_play_groups, "children_grade_r_age": children_grade_r_age, "ecd_centres_with_grade_r_learners": grade_r['centres_with_grade_r_learners'], "schools_with_grade_r_learners": schools_with_grade_r_learners }
def get_demographics_profile(geo, session): # population group pop_dist_data, total_pop = get_stat_data( ["population group"], geo, session, table_dataset="Census and Community Survey" ) # language language_data, _ = get_stat_data( ["language"], geo, session, table_dataset="Census and Community Survey", order_by="-total", ) language_most_spoken = language_data[language_data.keys()[0]] # age groups age_dist_data, total_age = get_stat_data( ["age groups in 5 years"], geo, session, table_dataset="Census and Community Survey", recode=COLLAPSED_AGE_CATEGORIES, key_order=( "0-9", "10-19", "20-29", "30-39", "40-49", "50-59", "60-69", "70-79", "80+", ), ) # sex sex_data, _ = get_stat_data( ["gender"], geo, session, table_universe="Population", table_dataset="Census and Community Survey", ) final_data = { "language_distribution": language_data, "language_most_spoken": language_most_spoken, "population_group_distribution": pop_dist_data, "age_group_distribution": age_dist_data, "sex_ratio": sex_data, "total_population": {"name": "People", "values": {"this": total_pop}}, } if geo.square_kms: final_data["population_density"] = { "name": "people per square kilometre", "values": {"this": total_pop / geo.square_kms}, } # median age/age category age_table = get_datatable("ageincompletedyears") objects = sorted( age_table.get_rows_for_geo(geo, session), key=lambda x: int(getattr(x, "age in completed years")), ) # median age median = calculate_median(objects, "age in completed years") final_data["median_age"] = {"name": "Median age", "values": {"this": median}} # age category age_dist, _ = get_stat_data( ["age in completed years"], geo, session, table_dataset="Census and Community Survey", table_name="ageincompletedyearssimplified", key_order=["Under 18", "18 to 64", "65 and over"], recode={"< 18": "Under 18", ">= 65": "65 and over"}, ) final_data["age_category_distribution"] = age_dist # citizenship citizenship_dist, _ = get_stat_data( ["citizenship"], geo, session, table_dataset="Census and Community Survey", order_by="-total", ) sa_citizen = citizenship_dist["Yes"]["numerators"]["this"] final_data["citizenship_distribution"] = citizenship_dist final_data["citizenship_south_african"] = { "name": "South African citizens", "values": {"this": percent(sa_citizen, total_pop)}, "numerators": {"this": sa_citizen}, } # migration province_of_birth_dist, _ = get_stat_data( ["province of birth"], geo, session, table_dataset="Census and Community Survey", exclude_zero=True, order_by="-total", ) final_data["province_of_birth_distribution"] = province_of_birth_dist def region_recode(field, key): if key == "Born in South Africa": return "South Africa" else: return {"Not applicable": "Other"}.get(key, key) region_of_birth_dist, _ = get_stat_data( ["region of birth"], geo, session, table_dataset="Census and Community Survey", exclude_zero=True, order_by="-total", recode=region_recode, ) if "South Africa" in region_of_birth_dist: born_in_sa = region_of_birth_dist["South Africa"]["numerators"]["this"] else: born_in_sa = 0 final_data["region_of_birth_distribution"] = region_of_birth_dist final_data["born_in_south_africa"] = { "name": "Born in South Africa", "values": {"this": percent(born_in_sa, total_pop)}, "numerators": {"this": born_in_sa}, } return final_data
def get_service_delivery_profile(geo, session): # water source water_src_data, total_wsrc = get_stat_data( ['source of water'], geo, session, recode=SHORT_WATER_SOURCE_CATEGORIES, order_by='-total') if 'Service provider' in water_src_data: total_water_sp = water_src_data['Service provider']['numerators']['this'] else: total_water_sp = 0.0 # electricity elec_attrs = ['electricity for cooking', 'electricity for heating', 'electricity for lighting'] db_model_elec = get_model_from_fields(elec_attrs, geo.geo_level) objects = get_objects_by_geo(db_model_elec, geo, session) total_elec = 0.0 total_some_elec = 0.0 elec_access_data = { 'total_all_elec': { "name": "Have electricity for everything", "numerators": {"this": 0.0}, }, 'total_some_not_all_elec': { "name": "Have electricity for some things", "numerators": {"this": 0.0}, }, 'total_no_elec': { "name": "No electricity", "numerators": {"this": 0.0}, } } for obj in objects: total_elec += obj.total has_some = False has_all = True for attr in elec_attrs: val = not getattr(obj, attr).startswith('no ') has_all = has_all and val has_some = has_some or val if has_some: total_some_elec += obj.total if has_all: elec_access_data['total_all_elec']['numerators']['this'] += obj.total elif has_some: elec_access_data['total_some_not_all_elec']['numerators']['this'] += obj.total else: elec_access_data['total_no_elec']['numerators']['this'] += obj.total for data, total in zip((elec_access_data,), (total_elec,)): for fields in data.values(): fields["values"] = {"this": percent(fields["numerators"]["this"], total)} add_metadata(elec_access_data, db_model_elec) # toilets toilet_data, total_toilet = get_stat_data( ['toilet facilities'], geo, session, exclude_zero=True, recode=COLLAPSED_TOILET_CATEGORIES, order_by='-total') total_flush_toilet = 0.0 total_no_toilet = 0.0 for key, data in toilet_data.iteritems(): if key.startswith('Flush') or key.startswith('Chemical'): total_flush_toilet += data['numerators']['this'] if key == 'None': total_no_toilet += data['numerators']['this'] return { 'water_source_distribution': water_src_data, 'percentage_water_from_service_provider': { "name": "Are getting water from a regional or local service provider", "numerators": {"this": total_water_sp}, "values": {"this": percent(total_water_sp, total_wsrc)}, }, 'percentage_electricity_access': { "name": "Have electricity for at least one of cooking, heating or lighting", "numerators": {"this": total_some_elec}, "values": {"this": percent(total_some_elec, total_elec)}, }, 'electricity_access_distribution': elec_access_data, 'percentage_flush_toilet_access': { "name": "Have access to flush or chemical toilets", "numerators": {"this": total_flush_toilet}, "values": {"this": percent(total_flush_toilet, total_toilet)}, }, 'percentage_no_toilet_access': { "name": "Have no access to any toilets", "numerators": {"this": total_no_toilet}, "values": {"this": percent(total_no_toilet, total_toilet)}, }, 'toilet_facilities_distribution': toilet_data, }
def get_children_profile(geo, session): profile = {} # age child_adult_dist, _ = get_stat_data( ["age in completed years"], geo, session, table_name="ageincompletedyearssimplified", recode={ "< 18": "Children (< 18)", "18 to 64": "Adults (>= 18)", ">= 65": "Adults (>= 18)", }, key_order=["Children (< 18)", "Adults (>= 18)"], ) # parental survival survival, total = get_stat_data(["mother alive", "father alive"], geo, session) parental_survival_dist = OrderedDict() parental_survival_dist["metadata"] = survival["metadata"] parental_survival_dist["Both parents"] = survival["Yes"]["Yes"] parental_survival_dist["Both parents"]["name"] = "Both parents" parental_survival_dist["Neither parent"] = survival["No"]["No"] parental_survival_dist["Neither parent"]["name"] = "Neither parent" parental_survival_dist["One parent"] = survival["Yes"]["No"] parental_survival_dist["One parent"]["numerators"]["this"] += survival["No"]["Yes"][ "numerators" ]["this"] rest = ( total - parental_survival_dist["Both parents"]["numerators"]["this"] - parental_survival_dist["Neither parent"]["numerators"]["this"] - parental_survival_dist["One parent"]["numerators"]["this"] ) parental_survival_dist["Uncertain"] = { "name": "Uncertain", "numerators": {"this": rest}, "values": {"this": percent(rest, total)}, } # gender gender_dist, _ = get_stat_data( ["gender"], geo, session, table_universe="Children under 18" ) # school # NOTE: this data is incompatible with some views (check out # https://github.com/censusreporter/censusreporter/issues/78) # # school_attendance_dist, total_school_aged = get_stat_data( # ['present school attendance', 'age in completed years'], # geo, session, # ) # school_attendance_dist['Yes']['metadata'] = \ # school_attendance_dist['metadata'] # school_attendance_dist = school_attendance_dist['Yes'] # total_attendance = sum(d['numerators']['this'] for d in # school_attendance_dist.values() # if 'numerators' in d) # school attendance school_attendance_dist, total_school_aged = get_stat_data( ["present school attendance"], geo, session, recode=COLLAPSED_ATTENDANCE_CATEGORIES, ) total_attendance = school_attendance_dist["Yes"]["numerators"]["this"] # education level education17_dist, _ = get_stat_data( ["highest educational level"], geo, session, table_universe="17-year-old children", recode=COLLAPSED_EDUCATION_CATEGORIES, key_order=EDUCATION_KEY_ORDER, ) # employment employment_dist, total_15to17 = get_stat_data( ["official employment status"], geo, session, table_universe="Children 15 to 17", exclude=["Not applicable"], ) total_in_labour_force = float( sum( v["numerators"]["this"] for k, v in employment_dist.iteritems() if COLLAPSED_EMPLOYMENT_CATEGORIES.get(k, None) == "In labour force" ) ) employment_indicators = { "percent_in_labour_force": { "name": "Of children between 15 and 17 are in the labour force", "numerators": {"this": total_in_labour_force}, "values": {"this": percent(total_in_labour_force, total_15to17)}, }, "employment_distribution": employment_dist, } # median income # monthly or annual if geo.version == "2011": income_dist_data, total_workers = get_stat_data( ["individual monthly income"], geo, session, table_universe="Children 15 to 17 who are employed", exclude=["Not applicable"], recode=COLLAPSED_MONTHLY_INCOME_CATEGORIES, key_order=COLLAPSED_MONTHLY_INCOME_CATEGORIES.values(), ) median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_MONTHLY_INCOME_CATEGORIES[median] employment_indicators.update( { "median_income": { "name": "Average monthly income of employed children between 15 and 17", "values": {"this": median_income}, } } ) else: income_dist_data, total_workers = get_stat_data( ["individual annual income"], geo, session, table_universe="Children 15 to 17 who are employed", exclude=["Not applicable"], recode=COLLAPSED_ANNUAL_INCOME_CATEGORIES, key_order=COLLAPSED_ANNUAL_INCOME_CATEGORIES.values(), ) median = calculate_median_stat(income_dist_data) median_income = ESTIMATED_ANNUAL_INCOME_CATEGORIES[median] employment_indicators.update( { "median_annual_income": { "name": "Average annual income of employed children between 15 and 17", "values": {"this": median_income}, } } ) profile.update( { "demographics": { "child_adult_distribution": child_adult_dist, "total_children": { "name": "Children", "values": { "this": child_adult_dist["Children (< 18)"]["numerators"][ "this" ] }, }, "gender_distribution": gender_dist, "parental_survival_distribution": parental_survival_dist, "percent_no_parent": { "name": "Of children 14 and under have no living biological parents", "values": parental_survival_dist["Neither parent"]["values"], "numerators": parental_survival_dist["Neither parent"][ "numerators" ], }, }, "school": { "school_attendance_distribution": school_attendance_dist, "percent_school_attendance": { "name": "School-aged children (5 to 17 years old) are in school", "numerators": {"this": total_school_aged}, "values": { "this": percent( float(total_attendance), float(total_school_aged) ) }, }, "education17_distribution": education17_dist, }, "employment": employment_indicators, } ) return profile
def get_ecd_centres_profile(geo, session): children_age_groups, total_children = get_stat_data( ['age in completed years'], geo, session, table_name='ageincompletedyears', only=['3', '4', '5', '6'], recode=ECD_AGE_CATEGORIES, percent=False, key_order=['0-2', '3-5', '6-7']) children_3_to_5 = children_age_groups['3-5']['values']['this'] # This will not be needed when the column names for centres are changed. reg_recode = { 'registration_incomplete-access_denied': 'Registration incomplete', 'registration_incomplete-closed': 'Registration incomplete', 'registration_incomplete-not_found': 'Registration incomplete', } table = get_datatable('ecd_centres_by_registration') ecd_centres_by_registration, total_ecd_centres = table.get_stat_data( geo, percent=True, recode=reg_recode) table = get_datatable('ecd_children_enrolled') children_enrolled, _ = table.get_stat_data(geo, percent=False) children_enrolled['children_enrolled_age_3_to_5'][ 'name'] = 'Children enrolled in ECD centres' children_3_to_5_coverage = percent( children_enrolled['children_enrolled_age_3_to_5']['values']['this'], children_3_to_5) children_3_to_5_per_ecd_centre = ratio(children_3_to_5, total_ecd_centres) children_3_to_5_per_ecd_centre_enrolled = ratio( children_enrolled['children_enrolled_age_3_to_5']['values']['this'], total_ecd_centres) table = get_datatable('ecd_centres_by_type') ecd_centres_by_type, _ = table.get_stat_data(geo, key_order=[ 'community_based', 'home_based', 'school_based', 'other', 'not_specified' ]) table = get_datatable('ecd_grade_r') grade_r, _ = table.get_stat_data(geo, percent=False) grade_r['centres_with_grade_r_learners'][ 'name'] = "Centres with Grade R learners" # Currently there's no data available for these datapoints. # They are displayed in the template to promote this fact. registered_ecd_programmes = { "name": "Registered ECD programmes", "values": { "this": None }, } children_in_ecd_programmes = { "name": "Children in programmes", "values": { "this": None }, } children_in_play_groups = { "name": "Children in play groups", "values": { "this": None }, } children_grade_r_age = { "name": "Children of Grade R age (6 years)", "values": { "this": children_age_groups['6']['values']['this'] } } schools_with_grade_r_learners = { "name": "Schools with Grade R learners", "values": { "this": None } } return { "total_ecd_centres": { "name": "Number of ECD centres", "values": { "this": total_ecd_centres } }, "ecd_centres_by_registration": ecd_centres_by_registration, "ecd_centres_by_type": ecd_centres_by_type, "registered_ecd_programmes": registered_ecd_programmes, "children_enrolled_age_3_to_5": children_enrolled['children_enrolled_age_3_to_5'], "children_3_to_5_coverage": { "name": "Children living in the area who are enrolled in ECD centres. (Children enrolled in centres / Children living in the area)", "values": { "this": children_3_to_5_coverage } }, "children_3_to_5_per_ecd_centre": { "name": "Average number of children living in the area for each ECD centre", "values": { "this": children_3_to_5_per_ecd_centre } }, "children_3_to_5_per_ecd_centre_enrolled": { "name": "Average number of children enrolled in each ECD centre", "values": { "this": children_3_to_5_per_ecd_centre_enrolled } }, "children_in_ecd_programmes": children_in_ecd_programmes, "children_in_play_groups": children_in_play_groups, "children_grade_r_age": children_grade_r_age, "ecd_centres_with_grade_r_learners": grade_r['centres_with_grade_r_learners'], "schools_with_grade_r_learners": schools_with_grade_r_learners }
def get_service_delivery_profile(geo, session): # water source water_src_data, total_wsrc = get_stat_data( ["source of water"], geo, session, recode=SHORT_WATER_SOURCE_CATEGORIES, order_by="-total", ) # water from a service provider total_water_sp = 0.0 perc_water_sp = 0.0 if current_context().get("year") == "latest": water_supplier_data, total_wspl = get_stat_data( ["supplier of water"], geo, session, recode=SHORT_WATER_SUPPLIER_CATEGORIES, order_by="-total", ) water_sp = ["Service provider", "Water scheme"] for key in water_sp: if key in water_supplier_data: total_water_sp += water_supplier_data[key]["numerators"]["this"] perc_water_sp = percent(total_water_sp, total_wspl) else: if "Service provider" in water_src_data: total_water_sp = water_src_data["Service provider"]["numerators"]["this"] perc_water_sp = percent(total_water_sp, total_wsrc) percentage_water_from_service_provider = { "name": "Are getting water from a regional or local service provider", "numerators": {"this": total_water_sp}, "values": {"this": perc_water_sp}, } # refuse disposal refuse_disp_data, total_ref = get_stat_data( ["refuse disposal"], geo, session, recode=SHORT_REFUSE_DISPOSAL_CATEGORIES, order_by="-total", ) total_ref_sp = 0.0 for k, v in refuse_disp_data.iteritems(): if k.startswith("Service provider"): total_ref_sp += v["numerators"]["this"] sp_name_2011 = ( "Are getting refuse disposal from a local authority or private company" ) sp_name_2016 = "Are getting refuse disposal from a local authority, private company or community members" percentage_ref_disp_from_service_provider = { "name": sp_name_2011 if str(current_context().get("year")) == "2011" else sp_name_2016, "numerators": {"this": total_ref_sp}, "values": {"this": percent(total_ref_sp, total_ref)}, } # electricity if geo.version == "2011" and str(current_context().get("year")) == "2011": elec_attrs = [ "electricity for cooking", "electricity for heating", "electricity for lighting", ] elec_table = get_datatable("electricityforcooking_electricityforheating_electr") objects = elec_table.get_rows_for_geo(geo, session) total_elec = 0.0 total_some_elec = 0.0 elec_access_data = { "total_all_elec": { "name": "Have electricity for everything", "numerators": {"this": 0.0}, }, "total_some_not_all_elec": { "name": "Have electricity for some things", "numerators": {"this": 0.0}, }, "total_no_elec": {"name": "No electricity", "numerators": {"this": 0.0}}, } for obj in objects: total_elec += obj.total has_some = False has_all = True for attr in elec_attrs: val = not getattr(obj, attr).startswith("no ") has_all = has_all and val has_some = has_some or val if has_some: total_some_elec += obj.total if has_all: elec_access_data["total_all_elec"]["numerators"]["this"] += obj.total elif has_some: elec_access_data["total_some_not_all_elec"]["numerators"][ "this" ] += obj.total else: elec_access_data["total_no_elec"]["numerators"]["this"] += obj.total set_percent_values(elec_access_data, total_elec) add_metadata( elec_access_data, elec_table, elec_table.get_release(current_context().get("year")), ) if current_context().get("year") == "latest": # We don't have this data for 2011 elec_access, _ = get_stat_data( ["access to electricity"], geo, session, table_universe="Population", recode=ELECTRICITY_ACCESS_RECODE, order_by="-total", ) # toilets toilet_data, total_toilet = get_stat_data( ["toilet facilities"], geo, session, exclude_zero=True, recode=COLLAPSED_TOILET_CATEGORIES, order_by="-total", ) total_flush_toilet = 0.0 total_no_toilet = 0.0 for key, data in toilet_data.iteritems(): if key.startswith("Flush") or key.startswith("Chemical"): total_flush_toilet += data["numerators"]["this"] if key == "None": total_no_toilet += data["numerators"]["this"] profile = { "water_source_distribution": water_src_data, "percentage_water_from_service_provider": percentage_water_from_service_provider, "refuse_disposal_distribution": refuse_disp_data, "percentage_ref_disp_from_service_provider": percentage_ref_disp_from_service_provider, "percentage_flush_toilet_access": { "name": "Have access to flush or chemical toilets", "numerators": {"this": total_flush_toilet}, "values": {"this": percent(total_flush_toilet, total_toilet)}, }, "percentage_no_toilet_access": { "name": "Have no access to any toilets", "numerators": {"this": total_no_toilet}, "values": {"this": percent(total_no_toilet, total_toilet)}, }, "toilet_facilities_distribution": toilet_data, } if current_context().get("year") == "latest": profile.update( { "water_supplier_distribution": water_supplier_data, "electricity_access": elec_access, "percentage_no_electricity_access": { "name": "Have no access to electricity", "numerators": elec_access["No access to electricity"]["numerators"], "values": elec_access["No access to electricity"]["values"], }, } ) if geo.version == "2011": profile.update( { "percentage_electricity_access": { "name": "Have electricity for at least one of cooking, heating or lighting", "numerators": {"this": total_some_elec}, "values": {"this": percent(total_some_elec, total_elec)}, }, "electricity_access_distribution": elec_access_data, } ) return profile
def get_service_delivery_profile(geo, session): # water source water_src_data, total_wsrc = get_stat_data( ['source of water'], geo, session, recode=SHORT_WATER_SOURCE_CATEGORIES, order_by='-total') if 'Service provider' in water_src_data: total_water_sp = water_src_data['Service provider']['numerators'][ 'this'] else: total_water_sp = 0.0 # electricity elec_attrs = [ 'electricity for cooking', 'electricity for heating', 'electricity for lighting' ] db_model_elec = get_model_from_fields(elec_attrs, geo.geo_level) objects = get_objects_by_geo(db_model_elec, geo, session) total_elec = 0.0 total_some_elec = 0.0 elec_access_data = { 'total_all_elec': { "name": "Have electricity for everything", "numerators": { "this": 0.0 }, }, 'total_some_not_all_elec': { "name": "Have electricity for some things", "numerators": { "this": 0.0 }, }, 'total_no_elec': { "name": "No electricity", "numerators": { "this": 0.0 }, } } for obj in objects: total_elec += obj.total has_some = False has_all = True for attr in elec_attrs: val = not getattr(obj, attr).startswith('no ') has_all = has_all and val has_some = has_some or val if has_some: total_some_elec += obj.total if has_all: elec_access_data['total_all_elec']['numerators'][ 'this'] += obj.total elif has_some: elec_access_data['total_some_not_all_elec']['numerators'][ 'this'] += obj.total else: elec_access_data['total_no_elec']['numerators'][ 'this'] += obj.total for data, total in zip((elec_access_data, ), (total_elec, )): for fields in data.values(): fields["values"] = { "this": percent(fields["numerators"]["this"], total) } add_metadata(elec_access_data, db_model_elec) # toilets toilet_data, total_toilet = get_stat_data( ['toilet facilities'], geo, session, exclude_zero=True, recode=COLLAPSED_TOILET_CATEGORIES, order_by='-total') total_flush_toilet = 0.0 total_no_toilet = 0.0 for key, data in toilet_data.iteritems(): if key.startswith('Flush') or key.startswith('Chemical'): total_flush_toilet += data['numerators']['this'] if key == 'None': total_no_toilet += data['numerators']['this'] return { 'water_source_distribution': water_src_data, 'percentage_water_from_service_provider': { "name": "Are getting water from a regional or local service provider", "numerators": { "this": total_water_sp }, "values": { "this": percent(total_water_sp, total_wsrc) }, }, 'percentage_electricity_access': { "name": "Have electricity for at least one of cooking, heating or lighting", "numerators": { "this": total_some_elec }, "values": { "this": percent(total_some_elec, total_elec) }, }, 'electricity_access_distribution': elec_access_data, 'percentage_flush_toilet_access': { "name": "Have access to flush or chemical toilets", "numerators": { "this": total_flush_toilet }, "values": { "this": percent(total_flush_toilet, total_toilet) }, }, 'percentage_no_toilet_access': { "name": "Have no access to any toilets", "numerators": { "this": total_no_toilet }, "values": { "this": percent(total_no_toilet, total_toilet) }, }, 'toilet_facilities_distribution': toilet_data, }
def get_education_profile(geo, session, display_profile, comparative=False): youth_completed_grade9, _ = get_stat_data( ['completed grade9'], geo, session, table_universe='Youth aged 16 to 17', table_dataset='Census and Community Survey', key_order=('Completed', 'Not completed')) youth_completed_grade9_by_gender, _ = get_stat_data( ['completed grade9', 'gender'], geo, session, table_universe='Youth aged 16 to 17', table_dataset='Census and Community Survey', percent_grouping=['gender'], slices=['Completed'], key_order={'gender': GENDER_ORDER}) youth_education_level, youth_pop_20_to_24 = get_stat_data( ['education level'], geo, session, table_universe='Youth aged 20 to 24', table_dataset='Census and Community Survey', key_order=EDUCATION_LEVEL_KEY_ORDER) youth_perc_matric = None if youth_education_level['Matric/matric equivalent']['numerators']['this']: matric_or_equiv = ( youth_education_level['Matric/matric equivalent']['numerators']['this'] + youth_education_level['Any tertiary']['numerators']['this']) youth_perc_matric = percent(matric_or_equiv, youth_pop_20_to_24) youth_education_attendance, _ = get_stat_data( ['attendance'], geo, session, table_universe='Youth', table_dataset='Census and Community Survey', table_fields=['attendance', 'age in completed years', 'gender']) youth_education_attending_by_age, _ = get_stat_data( ['attendance', 'age in completed years'], geo, session, table_universe='Youth', table_dataset='Census and Community Survey', table_fields=['attendance', 'age in completed years', 'gender'], table_name='youth_education_attendance_age_incompleted_years_gender', percent_grouping=['age in completed years'], slices=['Yes']) youth_education_attending_by_gender, _ = get_stat_data( ['attendance', 'gender'], geo, session, table_universe='Youth', table_dataset='Census and Community Survey', table_fields=['attendance', 'age in completed years', 'gender'], percent_grouping=['gender'], slices=['Yes'], key_order={'gender': GENDER_ORDER}) final_data = { 'youth_completed_grade9': youth_completed_grade9, 'youth_perc_completed_grade9': { 'name': 'Of youth aged 16-17 have completed grade 9 or higher', 'values': {'this': youth_completed_grade9['Completed']['values']['this']} }, 'youth_completed_grade9_by_gender': youth_completed_grade9_by_gender, 'youth_education_level': youth_education_level, 'youth_perc_matric': { "name": "Of youth aged 20-24 have completed matric/matric equivalent or higher", "values": {"this": youth_perc_matric} }, 'youth_perc_attending': { "name": "Of youth aged 15-24 attend an educational institution", "values": {"this": youth_education_attendance['Yes']['values']['this']} }, 'youth_education_attending_by_age': youth_education_attending_by_age, 'youth_education_attending_by_gender': youth_education_attending_by_gender, } if display_profile == 'WC': with dataset_context(year='2017'): youth_average_mean_score_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Average mean score in both language and mathematics', percent=False) youth_average_language_score_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Average score in language', percent=False) youth_average_maths_score_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Average score in mathematics', percent=False) youth_language_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Percentage passed in language', key_order={'outcome': ['Passed', 'Failed']}, percent=False, slices=['2017']) youth_maths_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Percentage passed in mathematics', key_order={'outcome': ['Passed', 'Failed']}, percent=False, slices=['2017']) with dataset_context(year='2017'): youth_matric_outcome_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Matric pass rate', only={'outcome': ['Passed']}, percent=False) youth_matric_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Matric pass rate', key_order={'outcome': ['Passed', 'Failed']}, percent=False, slices=['2017']) youth_matric_throughput_rate_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Matric passes as a % of grade 8 enrolment', only={'outcome': ['Passed']}, percent=False) youth_matric_throughput_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Matric passes as a % of grade 8 enrolment', key_order={'outcome': ['Passed', 'Dropped out or failed']}, percent=False, slices=['2017']) youth_bachelor_passes_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Bachelor passes as a % of grade 8 enrolment', only={'outcome': ['Bachelor pass']}, percent=False) youth_bachelor_outcome_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Bachelor passes as a % of grade 8 enrolment', key_order={'outcome': ['Bachelor pass', 'No bachelor pass']}, percent=False, slices=['2017']) youth_student_dropout_rate_by_year, _ = get_stat_data( ['year'], geo, session, table_universe='Dropout rates between grade 10 and matric', only={'outcome': ['Dropped out']}, percent=False) youth_student_dropout_rate_latest, _ = get_stat_data( ['year', 'outcome'], geo, session, table_universe='Dropout rates between grade 10 and matric', percent=False, slices=['2017']) final_data.update({ 'youth_ave_mean_score_latest': { "name": "Average mean score in both language and mathematics", "values": {"this": youth_average_mean_score_by_year['2017']['values']['this']} }, 'youth_ave_mean_score_by_year': youth_average_mean_score_by_year, 'youth_ave_language_score_latest': { "name": "Average score in language", "values": {"this": youth_average_language_score_by_year['2017']['values']['this']} }, 'youth_ave_language_score_by_year': youth_average_language_score_by_year, 'youth_ave_maths_score_latest': { "name": "Average score in mathematics", "values": {"this": youth_average_maths_score_by_year['2017']['values']['this']} }, 'youth_ave_maths_score_by_year': youth_average_maths_score_by_year, 'youth_language_outcome_latest': youth_language_outcome_latest, 'youth_maths_outcome_latest': youth_maths_outcome_latest, 'youth_matric_pass_rate_latest': { "name": "Of students writing matric passed", "values": {"this": youth_matric_outcome_latest['Passed']['values']['this']} }, 'youth_matric_outcome_latest': youth_matric_outcome_latest, 'youth_matric_outcome_by_year': youth_matric_outcome_by_year, 'youth_matric_throughput_rate_latest': { "name": "Of Grade 8 students go on to pass matric", "values": {"this": youth_matric_throughput_latest['Passed']['values']['this']} }, 'youth_matric_throughput_latest': youth_matric_throughput_latest, 'youth_matric_throughput_rate_by_year': youth_matric_throughput_rate_by_year, 'youth_bachelor_passes_latest': { "name": "Of Grade 8 students go on to pass matric with a bachelor's pass", "values": {"this": youth_bachelor_outcome_latest['Bachelor pass']['values']['this']} }, 'youth_bachelor_outcome_latest': youth_bachelor_outcome_latest, 'youth_bachelor_passes_by_year': youth_bachelor_passes_by_year, 'youth_student_dropout_rate_latest': { "name": "Of students drop out between grade 10 and matric", "values": {"this": youth_student_dropout_rate_latest['Dropped out']['values']['this']} }, 'youth_student_dropout_rate_by_year': youth_student_dropout_rate_by_year }) return final_data