Warm-Up Exercises

Some recursion problems

  1. Write a function, recursive_min, that returns the smallest value in a nested number list. Assume there are no empty lists or sublists:
test(recursive_min([2, 9, [1, 13], 8, 6]) == 1)
test(recursive_min([2, [[100, 1], 90], [10, 13], 8, 6]) == 1)
test(recursive_min([2, [[13, -7], 90], [1, 100], 8, 6]) == -7)
test(recursive_min([[[-13, 7], 90], 2, [1, 100], 8, 6]) == -13)
  1. Write a function count that returns the number of occurrences of target in a nested list:
test(count(2, []), 0)
test(count(2, [2, 9, [2, 1, 13, 2], 8, [2, 6]]) == 4)
test(count(7, [[9, [7, 1, 13, 2], 8], [7, 6]]) == 2)
test(count(15, [[9, [7, 1, 13, 2], 8], [2, 6]]) == 0)
test(count(5, [[5, [5, [1, 5], 5], 5], [5, 6]]) == 6)
test(count("a",
     [["this",["a",["thing","a"],"a"],"is"], ["a","easy"]]) == 4)
  1. Write a function flatten that returns a simple list containing all the values in a nested list:
test(flatten([2,9,[2,1,13,2],8,[2,6]]) == [2,9,2,1,13,2,8,2,6])
test(flatten([[9,[7,1,13,2],8],[7,6]]) == [9,7,1,13,2,8,7,6])
test(flatten([[9,[7,1,13,2],8],[2,6]]) == [9,7,1,13,2,8,2,6])
test(flatten([["this",["a",["thing"],"a"],"is"],["a","easy"]]) ==
              ["this","a","thing","a","is","a","easy"])
test(flatten([]) == [])

In [ ]:
"""
def flatten(lst):
    res = []
    for elem in lst:
        if type(elem) == type([]):
            res += flatten(elem)
            print(res)
        else:
            res.append(elem)
    return res
"""

def flatten(lst):
    res = []
    def f(lst):
        for elem in lst:
            if type(elem) == type([]):
                f(elem)
            else:
                res.append(elem)
        return res
    return f(lst)

def recursive_min(lst):
    return min(flatten(lst))

def count(val, lst):
    return flatten(lst).count(val)

In [ ]:
def f(lst=[]):
    lst.append(1)
    return lst

f()

In [ ]:
assert flatten([2,9,[2,"Hi Skip!",13,2],8,[2,6]]) == [2,9,2,"Hi Skip!",13,2,8,2,6]
assert flatten([[9,[7,1,13,2],8],[7,6]]) == [9,7,1,13,2,8,7,6]
assert flatten([[9,[7,1,13,2],8],[2,6]]) == [9,7,1,13,2,8,2,6]
assert flatten([["this",["a",["thing"],"a"],"is"],["a","easy"]]) == ["this","a","thing","a","is","a","easy"]
assert flatten([]) == []

In [ ]:
assert count(2, []) == 0
assert count(2, [2, 9, [2, 1, 13, 2], 8, [2, 6]]) == 4
assert count(7, [[9, [7, 1, 13, 2], 8], [7, 6]]) == 2
assert count(15, [[9, [7, 1, 13, 2], 8], [2, 6]]) == 0
assert count(5, [[5, [5, [1, 5], 5], 5], [5, 6]]) == 6
assert count("a", [["this",["a",["thing","a"],"a"],"is"], ["a","easy"]]) == 4

In [ ]:
assert recursive_min([2, 9, [1, 13], 8, 6]) == 1
assert recursive_min([2, [[100, 1], 90], [10, 13], 8, 6]) == 1
assert recursive_min([2, [[13, -7], 90], [1, 100], 8, 6]) == -7
assert recursive_min([[[-13, 7], 90], 2, [1, 100], 8, 6]) == -13

XML and JSON


In [ ]:
import xml.etree.ElementTree as ET

data = """
<person>
  <name>Chuck</name>
  <phone type="intl">
     +1 734 303 4456
   </phone>
   <email hide="yes"/>
</person>"""

tree = ET.fromstring(data)
print 'Name:',tree.find('name').text
print 'Attr:',tree.find('email').get('hide')

In [ ]:
import xml.etree.ElementTree as ET

input = """
<stuff>
    <users>
        <user x="2">
            <id>001</id>
            <name>Chuck</name>
        </user>
        <user x="7">
            <id>009</id>
            <name>Brent</name>
        </user>
    </users>
</stuff>"""

stuff = ET.fromstring(input)
lst = stuff.findall('users/user')
print 'User count:', len(lst)

for item in lst:
    print 'Name', item.find('name').text
    print 'Id', item.find('id').text
    print 'Attribute', item.get('x')

In [ ]:
import json

input = """
[
  { "id" : "001",
    "x" : "2",
    "name" : "Chuck"
  } ,
  { "id" : "009",
    "x" : "7",
    "name" : "Chuck"
  } 
]"""

info = json.loads(input)
print 'User count:', len(info)

for item in info:
    print 'Name', item['name']
    print 'Id', item['id']
    print 'Attribute', item['x']

Exercises

  1. Make some memes using a meme API. Use requests.
  2. Take a look at the google geocoding API. Try to send it a location (like Porland!) and get the latitude and longitude back.

APIs

Google Geocoding API


In [ ]:
import urllib
import json

serviceurl = 'http://maps.googleapis.com/maps/api/geocode/json?'

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

    url = serviceurl + urllib.urlencode({'sensor':'false', 
          'address': address})
    print 'Retrieving', url
    uh = urllib.urlopen(url)
    data = uh.read()
    print 'Retrieved',len(data),'characters'

    try: js = json.loads(str(data))
    except: js = None
    if 'status' not in js or js['status'] != 'OK':
        print '==== Failure To Retrieve ===='
        print data
        continue

    print json.dumps(js, indent=4)

    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

Security and API usage

  • API Keys

    Sometimes once you get your API key, you simply include the key as part of POST data or perhaps as a parameter on the URL when calling the API.

  • OAuth and OAuth2

    Other times, the vendor wants increased assurance of the source of the requests and so they add expect you to send cryptographically signed messages using shared keys and secrets. A very common technology that is used to sign requests over the Internet is called OAuth. You can read more about the OAuth protocol at http://www.oauth.net.

Playing with the twitter API

For this next sample program we will download these files: twurl.py, hidden.py, oauth.py, and twitter1.py from www.py4inf.com/code and put them all in a folder on your computer.

Follow the exercises at the bottom of the page here: http://www.pythonlearn.com/html-008/cfbook014.html