def render_col(my_data, headers, col, url=False, dataset=False): value = my_data[headers.index(col)] if not value: return {"raw": None, "pretty": "N/A", "name": "N/A"} attr_type = col if "_iocode" in col: attr_type = "iocode" if dataset: alt_type = "{}_{}".format(dataset, attr_type) if alt_type in attr_cache: attr_type = alt_type if attr_type not in attr_cache: if isinstance(value, basestring): return_value = value else: # do simple number formating return_value = num_format(value, col) name = return_value else: # lookup the attr object and get the name attr = fetch(value, attr_type) url_name = attr["url_name"] if "url_name" in attr and attr["url_name"] else attr["id"] attr = attr["display_name"] if "display_name" in attr else attr["name"] name = attr if attr_type in PROFILES or attr_type in CROSSWALKS: attr = u"<a href='{}'>{}</a>".format(url_for("profile.profile", attr_type=attr_type, attr_id=url_name), attr) return_value = attr if url: return_value = u"<span class='stat-span' data-url='{}'>{}</span>".format(url, return_value) return {"raw": value, "pretty": return_value, "name": name}
def growth(self, **kwargs): key = kwargs.get("key") fmt = kwargs.get("format", "pretty") offset = int(kwargs.get("offset", "0")) kwargs["format"] = "raw" if "_moe" in key: kwargs["row"] = str(0 + offset) dx2 = self.var(**kwargs) if not dx2 or dx2 == "N/A": dx2 = 0 kwargs["row"] = str(1 + offset) dx1 = self.var(**kwargs) if not dx1 or dx1 == "N/A": dx1 = 0 kwargs["key"] = key[:-4] kwargs["row"] = str(0 + offset) x2 = self.var(**kwargs) kwargs["row"] = str(1 + offset) x1 = self.var(**kwargs) if not x1 or x1 == "N/A" or not x2 or x2 == "N/A": return "N/A" f1 = (math.pow(-x2 / math.pow(float(x1), 2), 2) * math.pow(dx1, 2)) f2 = (math.pow(1 / x1, 2) * math.pow(dx2, 2)) value = math.sqrt(f1 + f2) else: kwargs["row"] = str(0 + offset) x2 = self.var(**kwargs) kwargs["row"] = str(1 + offset) x1 = self.var(**kwargs) if not x1 or x1 == "N/A" or not x2 or x2 == "N/A": return "N/A" else: value = (float(x2) - x1) / x1 if fmt == "text": return "{} {}".format(num_format(abs(value), "growth"), "growth" if value >= 0 else "decline") elif fmt == "pretty": return num_format(abs(value), "growth") else: return value
def sum(self, **kwargs): namespace = kwargs.get("namespace") key = kwargs.get("key") formatting = kwargs.get("format", "pretty") var_map = self.variables if var_map: if namespace in var_map: total = sum([ r[key]["raw"] for r in var_map[namespace] if r[key]["raw"] ]) if formatting == "pretty": return num_format(total, key) else: return total return "N/A" else: raise Exception("vars.yaml file has no variables")
def tileAPI(column): url = "{}{}&limit={}".format(API, column["url"], TILEMAX) r = requests.get(url).json() show = re.findall(r"show=([a-z_0-9]+)", url)[0] order = re.findall(r"order=([a-z_0-9]+)", url)[0] sumlevel = re.findall(r"sumlevel=([a-z_0-9]+)", url)[0] if show == "geo": sumlevel = sumlevelMap[sumlevel] data = datafold(r) for d in data: attr_id = d[show] attr = fetch(attr_id, show) slug = attr["url_name"] if attr["url_name"] else attr_id d["title"] = attr["display_name"] if "display_name" in attr else attr[ "name"] # d["subtitle"] = "{}: {}".format(DICTIONARY[order], num_format(d[order], order)) d["subtitle"] = SUMLEVELS[show][sumlevel]["label"] d["link"] = "/profile/{}/{}".format(show, slug) d["image"] = "/search/{}/{}/img".format(show, attr_id) d["type"] = { "icon": "/static/img/icons/{}.svg".format(show), "title": SUMLEVELS[show][sumlevel]["label"], "type": TYPEMAP[show], "depth": "{}".format(sumlevel).replace("_", " ") } column["icon"] = "/static/img/icons/{}.svg".format(show) column["data"] = data column["source"] = r["source"] if show in footMap: column["footer"] = { "link": "/search/?kind={}".format(show), "text": "{} more".format(num_format(footMap[show])) } return column
def stat(params, col="name", dataset=False, data_only=False, moe=False, truncate=0): # convert request arguments into a url query string rank = int(params.pop("rank", "1")) if "limit" in params: limit = int(params["limit"]) else: limit = 1 if rank > 1 and limit == 1: params["limit"] = rank query = RequestEncodingMixin._encode_params(params) url = "{}/api?{}".format(API, query) stat_url = "{}?{}&col={}&dataset={}&moe={}&rank={}".format(url_for("profile.statView"), query, col, dataset, moe, str(rank)) try: r = requests.get(url).json() except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return { "url": stat_url, "value": "N/A" } if data_only: return r else: r = datafold(r) if dataset == "stat": if isinstance(r[0][col], list): r = [{params["show"]:x} for x in r[0][col]] col = "name" if len(r) == 0: return { "url": stat_url, "value": "N/A" } # if the output key is 'name', fetch attributes for each return and create an array of 'name' values # else create an array of the output key for each returned datapoint vals = [] show = params["show"].split(",")[-1] if col == "ratio": if limit == 1: vals = sorted([v for k, v in r[0].iteritems() if k in params["required"].split(",")], reverse=True) if vals[0] == 0 or vals[1] == 0: val = 0 else: val = vals[0]/vals[1] return num_format(val, key=col) else: denom = max([d[params["order"]] for d in r[1:]]) return num_format(r[0][params["order"]]/denom, key=col) if col == "diff": return num_format(r[0][params["order"]] - r[1][params["order"]], key=col) if col in COLMAP or "-" in col: vals = datapivot(r, col.split("-"), sort="desc") vals = [v for v in vals[rank - 1:limit]] if moe: top = [v["moe"] for v in vals] else: top = [v["name"] for v in vals] vals = [v["value"] for v in vals] else: if rank > 1: r = r[rank-1:] if moe: top = [d[moe] for d in r] elif col == "name": if dataset in ["acs", "pums"]: attr = "{}_{}".format(dataset, show) else: attr = show top = [fetch(d[show], attr) for d in r] if attr in PROFILES or attr in CROSSWALKS: top = [(t["id"], t["display_name"] if "display_name" in t else t[col], t["url_name"] if "url_name" in t and t["url_name"] else t["id"]) for t in top] top = [u"<a href='{}'>{}</a>".format(url_for("profile.profile", attr_type=attr, attr_id=t[2]), t[1]) if attr != "geo" or t[0][:3] != "140" else t[1] for t in top] else: top = [t["display_name"] if "display_name" in t else t[col] for t in top] elif col == "id": top = [d[show] for d in r] else: top = [d[col] for d in r] if col != "id": if moe: col = moe top = [num_format(t, col) if isinstance(t, (int, float)) else t for t in top] # coerce all values to strings top = [u"{}".format(t) if t != "" else u"N/A" for t in top] if col == "id": top = u",".join(top) else: num_items = len(top) if truncate and num_items > truncate: top, rest = top[:int(truncate)], top[int(truncate):] # now stringify top = u"{}; <a href='#' class='show-more pri-link'>& {} more</a>".format(u"; ".join(top), len(rest)) if len(rest) > 1: rest = u"; ".join(rest) else: rest = u"and {}".join(rest[-1]) top = u"<span>{}</span><span class='the_rest'>{}</span>".format(top, rest) else: if num_items > 1: top[-1] = u"and {}".format(top[-1]) if num_items == 2: top = u" ".join(top) else: top = u"; ".join(top) # otherwise, return the list joined with commans return { "url": stat_url, "value": top, "data": vals }
def rank_max(self, **kwargs): return num_format(profile_cache[self.attr_type]["ranks"][self.sumlevel(**kwargs)], condense=False)
def percent(self, **kwargs): """str: 2 columns divided by one another """ attr_type = kwargs.get("attr_type", self.attr_type) attr_id = kwargs.get("attr_id", self.attr["id"]) r = {"num": 1, "den": 1} for t in r.keys(): key = kwargs.get(t) params = {} params["limit"] = 1 params["year"] = kwargs.get("year", "latest") params = param_format(params) t_type = kwargs.get("{}_type".format(t), attr_type) params["show"] = kwargs.get("show", t_type) params[t_type] = kwargs.get("{}_id".format(t), attr_id) params["exclude"] = kwargs.get("exclude", kwargs.get("{}_exclude".format(t), "")) if "top:" in key: params["col"], params["force"] = key.split(":")[1].split(",") r["{}_key".format(t)] = params["col"] r[t] = self.top(**params)["data"][0] elif "var:" in key: keys = key.split(":")[1].split(",") if len(keys) == 2: keys.append(None) ns, col, row = keys r["{}_key".format(t)] = col r[t] = self.var(namespace=ns, key=col, row=row, format="raw") elif "," in key: num, den = key.split(",") subparams = {} subparams["num"] = num subparams["den"] = den subparams["data_only"] = True subparams["num_id"] = params[t_type] subparams["den_id"] = params[t_type] r["{}_key".format(t)] = None r[t] = self.percent(**subparams) else: params["required"] = key r["{}_key".format(t)] = key # convert request arguments into a url query string query = RequestEncodingMixin._encode_params(params) url = u"{}/api?{}".format(API, query) try: r[t] = datafold(requests.get(url).json()) except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return "N/A" if len(r[t]) == 0: return "N/A" r[t] = r[t][0][key] if r[t] in [None, "N/A"]: return "N/A" diff = kwargs.get("diff", False) text = kwargs.get("text", False) if text and text in TEXTCOMPARATORS: r["num"] = float(num_format(r["num"], r["num_key"], False, suffix=False).replace(",", "")) r["den"] = float(num_format(r["den"], r["den_key"], False, suffix=False).replace(",", "")) if r["num"] == 0 or r["den"] == 0: val = 0 elif diff: val = r["num"] - r["den"] else: val = float(r["num"])/float(r["den"]) if kwargs.get("invert", False): val = 1 - val if kwargs.get("data_only", False): return val if text and text in TEXTCOMPARATORS: text = TEXTCOMPARATORS[text] if diff: if val > 0: return text[0] elif val < 0: return text[1] else: return text[2] else: if val > 1: return text[0] elif val < 1: return text[1] else: return text[2] elif diff or kwargs.get("ratio", False): return num_format(abs(val)) else: return "{}%".format(num_format(val * 100))
def home(): g.page_type = "home" carousels = [] maps = [ "/map/?level=county&key=total_reimbursements_b", "/map/?level=county&key=income_below_poverty:pop_poverty_status,income_below_poverty,income_below_poverty_moe,pop_poverty_status,pop_poverty_status_moe", "/map/?level=state&key=high_school_graduation", "/map/?level=county&key=children_in_singleparent_households", "/map/?level=state&key=violent_crime" ] mapTotal = 0 for section in mapdata: mapTotal = mapTotal + len(mapdata[section]) carousels.append({ "title": "Maps", "icon": "/static/img/icons/demographics.svg", "data": tileMaps(maps), "footer": { "link": "/map", "text": "{} more".format(mapTotal - TILEMAX) } }) carousels.append({ "title": "Cities & Places", "icon": "/static/img/icons/geo.svg", "data": tileProfiles([ "geo/new-york-ny", "geo/los-angeles-county-ca", "geo/florida", "geo/suffolk-county-ma", "geo/illinois" ]), "footer": { "link": "/search/?kind=geo", "text": "{} more".format(num_format(footMap["geo"] - TILEMAX)) } }) carousels.append({ "rank": "naics", "title": "Industries", "icon": "/static/img/icons/naics.svg", "data": tileProfiles([ "naics/622", "naics/23", "naics/31-33", "naics/722Z", "naics/44-45" ]), "footer": { "link": "/search/?kind=naics", "text": "{} more".format(num_format(footMap["naics"] - TILEMAX)) } }) carousels.append({ "rank": "soc", "title": "Jobs", "icon": "/static/img/icons/soc.svg", "data": tileProfiles([ "soc/252020", "soc/151131", "soc/1110XX", "soc/412031", "soc/291141" ]), "footer": { "link": "/search/?kind=soc", "text": "{} more".format(num_format(footMap["soc"] - TILEMAX)) } }) carousels.append({ "rank": "cip", "title": "Higher Education", "icon": "/static/img/icons/cip.svg", "data": tileProfiles([ "cip/513801", "cip/110701", "cip/520201", "cip/420101", "cip/240101" ]), "footer": { "link": "/search/?kind=cip", "text": "{} more".format(num_format(footMap["cip"] - TILEMAX)) } }) cartDatasets = [{ "url": "{}/api/?required=patients_diabetic_medicare_enrollees_65_75_lipid_test_total&show=geo&sumlevel=county&year=all" .format(API), "slug": "map_patients_diabetic_medicare_enrollees_65_75_lipid_test_total_ county", "image": "/static/img/splash/naics/5417.jpg", "title": "Diabetic Lipid Tests by County", "new": 1 }, { "url": "{}/api/?required=adult_smoking&show=geo&sumlevel=state&year=all". format(API), "slug": "map_adult_smoking_ state", "image": "/static/img/splash/naics/3122.jpg", "title": "Adult Smoking by State" }, { "url": "{}/api/?required=leg_amputations_per_1000_enrollees_total&show=geo&sumlevel=county&year=all" .format(API), "slug": "map_leg_amputations_per_1000_enrollees_total_ county", "image": "/static/img/splash/naics/62.jpg", "title": "Leg Amputations by County", "new": 1 }, { "url": "{}/api/?required=pop%2Cpop_moe&show=geo&sumlevel=county&year=all". format(API), "slug": "map_pop_ county", "image": "/static/img/splash/cip/45.jpg", "title": "Population by County" }, { "url": "{}/api/?required=median_property_value%2Cmedian_property_value_moe&show=geo&sumlevel=county&year=all" .format(API), "slug": "map_median_property_value_ county", "image": "/static/img/splash/geo/05000US25019.jpg", "title": "Median Property Value by County" }] carousels.append({ "rank": "cart", "title": "Download", "icon": "/static/img/cart-big.png", "data": cartDatasets, "footer": { "link": "/cart", "text": "View Cart" } }) stories = StoryPreview.generate_list()[0] story_order = [ "opioid-addiction", "poverty-health", "worker-evolution", "medicare-physicians", "hardest-working" ] stories.sort( key=lambda story: story_order.index(story.story_id.split("_")[1]) if story.story_id.split("_")[1] in story_order else TILEMAX) now = datetime.datetime.now() for i, story in enumerate(stories): delta = now - story._date_obj stories[i] = { "new": int(delta.days) < 30, "link": "/story/{}".format(story.story_id), "image": story.background_image, "title": story.title, "subtitle": "By {}".format(story.authors[0]["name"]), "type": { "icon": "/static/img/icons/about.svg", "title": TYPEMAP["story"], "type": "story" } } carousels.append({ "rank": "story", "title": "Latest Stories", "icon": "/static/img/icons/about.svg", "data": stories[:TILEMAX], "footer": { "link": "/story/", "text": "{} more".format(len(stories) - TILEMAX) } }) return render_template("general/home.html", carousels=carousels)