-2

Im trying to get the average of "active" for each place under a specific area. So say the output would be ("Andaman and Nicobar Islands": 10, "Andhra Pradesh": 12) however i get type error string indices must be integers from the "r[v["recovered"]].append(v["deceased"])"

import requests, json
from collections import defaultdict
from statistics import mean

# request and parse the data
response_API = requests.get("https://data.covid19india.org/state_district_wise.json").json()

def get_mean_active(response_API):
    r = defaultdict(list)
    for v in response_API.values():
        r[v["area"]].append(v["active"])
    return {k: mean(v) for k, v in r}


print(
    get_mean_active(
        response_API["Andaman and Nicobar Islands"]["districtData"]["top level here"]
    )
)

TypeError: string indices must be integers
PS C:\Users\e\AppData\Local\Programs\Python\Python39\test>  c:; cd 'c:\Users\e\AppData\Local\Programs\Python\Python39\test'; & 'C:\User  File "C:\Users\e\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 268, in run_path    return _run_module_code(code, init_globals, run_name,
  File "C:\Users\e\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "C:\Users\e\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "c:\Users\e\AppData\Local\Programs\Python\Python39\test\ex2.py", line 19, in <module>
    get_mean_active(
  File "c:\Users\e\AppData\Local\Programs\Python\Python39\test\ex2.py", line 14, in get_mean_active
    r[v["Andaman and Nicobar Islands"]].append(v["active"])
TypeError: string indices must be integers
PS C:\Users\e\AppData\Local\Programs\Python\Python39\test>
nataku
  • 5
  • 5
  • If this code works, why are you here? If not, explain the *specifics* of the problem. – Scott Hunter Apr 21 '22 at 19:30
  • @ScottHunter it doesnt work i cant seem to pull the specific data to form the desired output, im currently getting Typerror: string indices must be integers. – nataku Apr 21 '22 at 19:35
  • I get a different error. There exists no `r[v["recovered"]].append(v["deceased"])` in the provided code. Please post the actual code and a full stack trace. – Michael Ruth Apr 21 '22 at 19:40
  • @MichaelRuth Sorry about that, my mistake. now ive updated it to what it should be. – nataku Apr 21 '22 at 19:49
  • What is `top level here`? I don't see that in the JSON. Are you replacing that with a district name? – Barmar Apr 21 '22 at 19:50
  • I don't think you need that at all. I think you want to loop over all the districts, not the values in a single district. The values are integers and strings, not dictionaries. – Barmar Apr 21 '22 at 19:51
  • But what is `v["area"]` supposed to be? I don't see that in the JSON. – Barmar Apr 21 '22 at 19:52
  • The error originates in `get_mean_price_by_submodel` but the code includes only `get_mean_active`. Please post a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) with the associated stack trace. – Michael Ruth Apr 21 '22 at 19:57
  • @Barmar yes exactly its a place holder for the district name, interesting. So in the "top level here" would go district data and at that do i need to use json.dumps? "v["area]" is supposed to take the district name. – nataku Apr 21 '22 at 19:57
  • @MichaelRuth again mistake on my part, traceback is updated and everything is as it should be. Currently getting error "r[v["Andaman and Nicobar Islands"]].append(v["active"]) TypeError: string indices must be integers" – nataku Apr 21 '22 at 20:03
  • I don't understand why you're calling `mean()`. Each area only has one element in the district data, so the mean is the same as the value. – Barmar Apr 21 '22 at 20:16

1 Answers1

0

The argument you're passing is going too deep into the nested dictionaries. You want to pass the entire districtData dictionary to get_mean_active(), not a specific area. Then the function loops over all the areas.

The loop should use .items(), not .values(), because the area name is the key of each dictionary element, not an element of the nested dictionary.

And the dictionary comprehension at the end needs to use r.items().

import requests, json
from collections import defaultdict
from statistics import mean

# request and parse the data
response_API = requests.get("https://data.covid19india.org/state_district_wise.json").json()

def get_mean_active(response_API):
    r = defaultdict(list)
    for area, v in response_API.items():
        r[area].append(v["active"])
    return {k: mean(v) for k, v in r.items()}


print(
    get_mean_active(
        response_API["Andaman and Nicobar Islands"]["districtData"]
    )
)

Result:

{'Nicobars': 0, 'North and Middle Andaman': 0, 'South Andaman': 19, 'Unknown': -13}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Very much appreciate your assistance @Barmar the reason i used mean was because i was going through a level up from your code. So say, the results from your output would all be in one key {"Andaman and Nicobar Islands": 6}, {"Andhra Pradesh": 1227 } getting the area and the average to all witin the area. – nataku Apr 21 '22 at 20:29
  • But you're calling the function on just `Andaman and Nicobar Islands`. It seems like you should be calculating the mean outside the function, when you loop over the districts. – Barmar Apr 21 '22 at 20:42
  • Or maybe you just need `return mean(v['active'] for v in response_API.values())` – Barmar Apr 21 '22 at 20:43
  • Currenlty trying those approaches, this has been a great help. – nataku Apr 21 '22 at 20:50