Fiona Daniel
Fiona Daniel

Reputation: 35

Extract two-character country code from the retrieved data in Python

I am learning Python from coursera and following is an optional exercise in the book, I am solving for practice.

Change either the www.py4e.com/code3/geojson.py or www.py4e.com/code3/geoxml.py to print out the two-character country code from the retrieved data. Add error checking so your program does not traceback if the country code is not there. Once you have it working, search for “Atlantic Ocean” and make sure it can handle locations that are not in any country.

Following is the code I have written but I don't understand what should I do next and I didn't understand the exact requirements of this question and wondering what would the output look like? What should be the sample execution like? And what should I try to enter code, country, county or a university name? Any help and insights would be greatly appreciated!

import urllib.request, urllib.parse, urllib.error
import json
import ssl

api_key = False
# If you have a Google Places API key, enter it here
# api_key = 'AIzaSy___IDByT70'
# https://developers.google.com/maps/documentation/geocoding/intro

if api_key is False:
    api_key = 42
    serviceurl = 'http://py4e-data.dr-chuck.net/json?'
else :
    serviceurl = 'https://maps.googleapis.com/maps/api/geocode/json?'

# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

while True:
    address = input('Enter location: ')
    if len(address) < 1: break

    parms = dict()
    parms['address'] = address
    if api_key is not False: parms['key'] = api_key
    url = serviceurl + urllib.parse.urlencode(parms)

    print('Retrieving', url)
    uh = urllib.request.urlopen(url, context=ctx)
    data = uh.read().decode()
    print('Retrieved', len(data), 'characters')

    try:
        js = json.loads(data)
    except:
        js = None

    if not js or 'status' not in js or js['status'] != 'OK':
        print('==== Failure To Retrieve ====')
        print(data)
        continue

    print(json.dumps(js, indent=4))

In any case I am getting the following error for whatever I am entering: Enter location: Drexel Retrieving http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=Drexel Retrieved 237 characters ==== Failure To Retrieve ==== b'{\n "error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",\n "results" : [],\n "status" : "REQUEST_DENIED"\n}\n' Enter location:

Upvotes: 0

Views: 1313

Answers (1)

Vyshak Puthusseri
Vyshak Puthusseri

Reputation: 533

I will answer this as two parts.

Part 1 : to avoid the above error.

You can of course use the Google Places API key, but as this is for educational purpose( An alternative is there within the course itself, http://py4e-data.dr-chuck.net )

The above error occurs due to the wrong API key. ( This code runs perfectly in my system.) Still if you are facing the same issue, remove the following code block

api_key = False
if api_key is False:
    api_key = 42
    serviceurl = 'http://py4e-data.dr-chuck.net/json?'
else :
    serviceurl = 'https://maps.googleapis.com/maps/api/geocode/json?'

and replace with only the following two line

api_key = 42
serviceurl = 'http://py4e-data.dr-chuck.net/json?'

So here only the data from this website will be used.( not form the Google Place API).

Part 2:

For this, first check if it was a country or not. Then print the 'short_name' of the country in the 'address_component' Please find the code below

import urllib.request, urllib.parse, urllib.error
import json
import ssl

api_key = False
if api_key is False:
    api_key = 42
    serviceurl = 'http://py4e-data.dr-chuck.net/json?'
else :
    serviceurl = 'https://maps.googleapis.com/maps/api/geocode/json?'

# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

while True:
    address = input('Enter location: ')
    if len(address) < 1: break
    parms = dict()
    parms['address'] = address
    if api_key is not False: parms['key'] = api_key
    url = serviceurl + urllib.parse.urlencode(parms)
    print('Retrieving', url)
    uh = urllib.request.urlopen(url, context=ctx)
    data = uh.read().decode()
    print('Retrieved', len(data), 'characters')
    try:
        js = json.loads(data)
    except:
        js = None
    if not js or 'status' not in js or js['status'] != 'OK':
        print('==== Failure To Retrieve ====')
        print(data)
        continue
    lat = js['results'][0]['geometry']['location']['lat']
    lng = js['results'][0]['geometry']['location']['lng']
    # print('lat', lat, 'lng', lng)
    location = js['results'][0]['formatted_address']
    # print(location)
    results = js['results'][0]
    address_components = results["address_components"]
    is_a_country = False
    try:
        for elem in address_components:
            types = elem["types"]
            if types == ["country", "political"]:
                is_a_country = True
                print("The two-character country code from the retrieved data is:", elem["short_name"])
        if not is_a_country:
            raise Exception
    except:
        print("There is no country code for that location.")

For more visual understanding go to the address printed by this code . You can see the json object of the current request. A sample is given below The JSON object of the place URUVACHAL, in INDIA

Just print the value of the short_name for that particular type for your answer.

Upvotes: 2

Related Questions