-1

Scripting Language: Python 3.6

Reference Book: Python Data Visualization Cookbook [Milovanović 2013-11-25]


Teaching myself Python Data Visualization

When I execute code from book

import requests

url = 'https://github.com/timeline.json'

r = requests.get(url)
json_obj = r.json()

repos = set() # we want just unique urls
for entry in json_obj:
    try:
        repos.add(entry['repository']['url'])
    except KeyError as e:
        print ("No key %s. Skipping..." % (e))

from pprint import pprint 
pprint(repos)

I get error

repos.add(entry['repository']['url'])
TypeError: string indices must be integers

How to troubleshoot? When I see similar threads, I draw a blank

Is the code from book even correct?

[As an aside, where did set() in repos = set() come from?]

Please point me in the right direction

Rhonda
  • 1,661
  • 5
  • 31
  • 65
  • 2
    From the json_obj: Hello there, wayfaring stranger. If you're reading this then you probably didn't see our blog post a couple of years back announcing that this API would go away: http://git.io/17AROg Fear not, you should be able to get what you need from the shiny new Events API instead. – francisco sollima Oct 10 '17 at 18:11

4 Answers4

2

If you print the json_obj you get this:

{'message': 'Hello there, wayfaring stranger. If you’re reading this then you pr
obably didn’t see our blog post a couple of years back announcing that this API 
would go away: http://git.io/17AROg Fear not, you should be able to get what you
 need from the shiny new Events API instead.', 'documentation_url': 'https://dev
eloper.github.com/v3/activity/events/#list-public-events'}

So this link seems to be old and you will have to look the new one up.

For your second question: set() is a data container similar to dict() and list(). sets are similar to lists in that they store a number of objects. The biggest differences are:

  • sets are not sorted (like dictionaries)
  • sets only contain unique items

You can find more info in the python documentation: https://docs.python.org/3/tutorial/datastructures.html#sets

I hope this helps, good luck with your learning.

I.P.
  • 161
  • 1
  • 1
  • 10
1

Just so you get some answers to your questions...

The TypeError: string indices must be integers is because, since the API is down, entry is now only a string (u'documentation_url'), and when entry['repository'] it raises an error because, with strings, you can only get the n-th character from an integer n (you can't get the repository-th character).

[As an aside, where did set() in repos = set() come from?]

When you do repos = set() you're only creating an empty set object an assigning it to repos. You would fill it later with repos.add(entry['repository']['url'])

francisco sollima
  • 7,952
  • 4
  • 22
  • 38
1

The entry object you are trying to access is a string, so you cannot access it with non-integer indices. I tried running your code and the url seems to be down or blocked because of too many requests, so this might be the reason why entry ends up becoming a string object.

the repos = set() means that, when you add new urls to repos it will ignore cases where that url is already in the set so you don't end up with duplicates. If you used repos = [] instead you would have to manually check for duplicates at every insertion (unless you wanted to allow duplicates).

You can read more about the set() data structure here: https://docs.python.org/3/tutorial/datastructures.html

Kevin Liu
  • 378
  • 2
  • 13
1

The API being used is obsolete. The following code uses the current API:

import requests
url = 'https://api.github.com/events' # New API URL

r = requests.get(url)
json_obj = r.json()

repos = set() # we want just unique urls
for entry in json_obj:
    try:
        repos.add(entry['repo']['url'])  # Key change. 'repo' not 'repository'
    except KeyError as e:
        print ("No key %s. Skipping..." % (e))

from pprint import pprint 
pprint(repos)

As others have pointed out set() creates a set object, which can only contain unique values. Example:

>>> set([1,2,3,4,4,5,5,6,6])
{1, 2, 3, 4, 5, 6}

Note that a set is unordered, so don't depend on the items being sorted as they seem to be in the example.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251