2

I am currently trying to figure out how to parse JSON information in Python and am having a harder time than I think I should.

Below is a sample of the information I am trying to parse.

{
  "2019-05-09": {
    "1. open": "124.2900",
    "2. high": "125.7800",
    "3. low": "123.5700",
    "4. close": "125.5000",
    "5. volume": "23491093"
  },
  "2019-05-08": {
    "1. open": "125.4400",
    "2. high": "126.3700",
    "3. low": "124.7500",
    "4. close": "125.5100",
    "5. volume": "25775583"
  },
  "2019-05-07": {
    "1. open": "126.4600",
    "2. high": "127.1800",
    "3. low": "124.2200",
    "4. close": "125.5200",
    "5. volume": "36017661"
  }
}

I am trying to store each day into a class so that I can parse the information.

In the below example, I am only trying to print the opening for these records. According to the simple examples I've looked at, this should work but always comes up with the error 'string indices must be integers.'

from alpha_vantage.timeseries import TimeSeries
import json

class day_history:
    def __init__(self, date, open, high, low, close, volume):
        self.date = date
        self.open = open
        self.high = high
        self.low = low
        self.close = close
        self.volume = volume

alpha_adv_key = "aaaaaaaaaaa"

ts = TimeSeries(key=alpha_adv_key)
data, meta_data = ts.get_daily(symbol='MSFT')

results = json.dumps(data)

for day in results:
    print(day["1. open"])

What is the correct way to parse this JSON data so that I can store it in the class?

1

1 Answer 1

1

If you want to turn it into a class see my code below.

That being said I think the issue you are having is for day in results:. This is going to return each key (i.e. a string). I think you meant to do for day in results.values(): which will return all the dictionaries.

Turning the json into a class.

You can just use the magic of unpacking using **. I used your input as a parameter d.

days = []
for day, info in d.items():
    temp = info.copy() # A copy because we don't want to change the original
    keys = list(temp.keys()) # List of all keys (Ex: 1. open)

    # We want to remove the beginning number so we just have
    # the wanted attribute name(Ex: open instead of 1. open)
    for key in keys:
        temp[key[3:]] = temp.pop(key)
    temp['date'] = day # Add our date to the temp dictionary

    # note the ** notation. This unpacks a dictionary to keyword arguments
    # so it would be like passing: (date=day, open=..., close=..., ...)
    # that is why I had to remove the numbers before the variable name.
    days.append(day_history(**temp)) # Pass this new dict to our constructor

# This will print out all the days
print(days)

I added a __repr__ method to your class to print them:

    def __repr__(self):
        return str(self.date) + str(self.high)

If you don't need more class methods you may just want to consider using a namedtuple:

from collections import namedtuple

Day_History = namedtuple("Day_History", "date open high low close volume")
days = []

for day, info in d.items():
    temp = info.copy()
    keys = list(temp.keys())
    for key in keys:
        temp[key[3:]] = temp.pop(key)
    temp['date'] = day
    days.append(Day_History(**temp))

for day in days:
    print(day)

Output:

Day_History(date='2019-05-09', open='124.2900', high='125.7800', low='123.5700', close='125.5000', volume='23491093')
Day_History(date='2019-05-08', open='125.4400', high='126.3700', low='124.7500', close='125.5100', volume='25775583')
Day_History(date='2019-05-07', open='126.4600', high='127.1800', low='124.2200', close='125.5200', volume='36017661')

and you cant print namedtuple parameters by doing something like:

for day in days:
    print(day.open)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.