Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

1. Have a GUI that enables the user to enter a location and search terms. 2. Que

ID: 3834269 • Letter: 1

Question

1. Have a GUI that enables the user to enter a location and search terms.

2. Query Twitter and Flickr to gather tweets and photos based on the search terms and the location.

3. Display a static map with markers showing the locations of the tweets and photos returned by the search.

4. Provide a way for users to view the tweets. E.g. you could place a Label or similar widget somewhere on your GUI and display the "current" tweet on it, where current corresponds to one of the mapped tweets. The marker corresponding to that "current" tweet should look different than other markers. Users might then acccess other tweets though "Next Tweet"/"Previous Tweet" buttons.

5. Provide a way to open a browser displaying the web page corresponding to URLs embedded in the tweets.

6. Provide a way for users to view the Flickr photos. E.g. you might add an additional Label or Canvas widget on the GUI and display the "current" photo on it. Like for tweets, the marker corresponding to that "current" photo should look different than other markers..

My code:

import tkinter
from tkinter import *
import math
from urllib.request import urlopen, urlretrieve
from urllib.parse import urlencode
import json

# To use, see the last function in this file, startGUI().

# Given a string representing a location, return 2-element
# [latitude, longitude] list for that location
#
# See https://developers.google.com/maps/documentation/geocoding/
# for details
#
def geocodeAddress(addressString):

urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
adst = urlencode({'address': addressString})
url = urlbase + adst

resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['geometry']['location']
return (float(loc['lat']),float(loc['lng']))

#
# Google will also "reverse geocode." That is, you can provide a latitude and longitude and
# and Google will try to provide "human readable" information about that location.
#
# E. g. geocodeLatLng(41.6613, -91.5361)
#
# Again, see https://developers.google.com/maps/documentation/geocoding/
#
def geocodeLatLng(lat, lng):
urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
latLngstring = "{},{}".format(lat,lng)
adst = urlencode({'latlng': latLngstring})
url = urlbase+adst
resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['addressFormat']
return loc


# Contruct a Google Static Maps API URL that specifies a map that is:
# - width-by-height in size (in pixels)
# - is centered at latitude lat and longitude long
# - is "zoomed" to the give Google Maps zoom level
#
# See https://developers.google.com/maps/documentation/static-maps/
#
# YOU WILL NEED TO MODIFY THIS TO BE ABLE TO
# 1) DISPLAY A PIN ON THE MAP
# 2) SPECIFY MAP TYPE - terrain vs road vs ...
#
def getMapUrl(width, height, lat, lng, zoom):
urlbase = "http://maps.google.com/maps/api/staticmap?"
parameter = "center={},{}&zoom={}&size={}x{}&format=gif".format(lat,lng,zoom,width,height)
return urlbase+parameter

# Retrieve a map image via Google Static Maps API:
# - centered at the location specified by global variable mapLocation
# - zoomed according to global variable zoomLevel (Google's zoom levels range from 0 to 21)
# - width and height equal to global variable mapSize
# Store the returned image in file name specified by global variable mapFileName
#
def retrieveMap():
lat, lng = geocodeAddress(mapLocation)
url = getMapUrl(mapSize, mapSize, lat, lng, zoomLevel)
urlretrieve(url, mapFileName)
return mapFileName

##########
# very basic GUI code

# Global variables used by GUI and map code
#

rootWindow = None
mapLabel = None

defaultLocation = "Mauna Kea, Hawaii"
mapLocation = defaultLocation
mapFileName = 'googlemap.gif'
mapSize = 400
zoomLevel = 9

def readEntryAndShowMap():
global mapLocation
global E
#### you should change this function to read from the location from an Entry widget
#### instead of using the default location
mapLocation = E.get()
showMap()
  
def showMap():
retrieveMap()
mapImage = tkinter.PhotoImage(file=mapFileName)
mapLabel.configure(image=mapImage)
# next line necessary to "prevent (image) from being garbage collected" - http://effbot.org/tkinterbook/label.htm
mapLabel.mapImage = mapImage
  
def initializeGUIetc():
global rootWindow
global mapLabel
global E

rootWindow = tkinter.Tk()
rootWindow.title("HW 10")

mainFrame = tkinter.Frame(rootWindow)
mainFrame.pack()

# until you add code, pressing this button won't change the map.
# you need to add an Entry widget that allows you to type in an address
# The click function should extract the location string from the Entry widget and create
# the appropriate map.

locationLabel = tkinter.Label(mainFrame, text="Enter Location.", bd = 1)
locationLabel.pack()

E = Entry(rootWindow, bd = 5)
E.pack()

readEntryAndShowMapButton = tkinter.Button(mainFrame, text="Show me the map!", command=readEntryAndShowMap)
readEntryAndShowMapButton.pack()

# we use a tkinter Label to display the map image

mapLabel = tkinter.Label(mainFrame, bd=2, relief=tkinter.FLAT)
mapLabel.pack()

def startGUI():
initializeGUIetc()
showMap()
rootWindow.mainloop()

Extend your HW 9 Q2 program so that it displays a map showing locations of Twitter tweets and Flickr photos matching user-specific search tenn The program should GUI and search query Twitter and ckr to gather ets and photos based h te and the location. display a static p with markers showing the locat the tweets and photos retumed by the search. provide a way for users to view the tweets. Eg you could place a Label or similar widget somewhere or your GUI and display the "cament' tweet on it, where current comesponds to one of the mapped tweets. The marker comesponding to that enrrent tweet should look different than ccher ight then ther tweets though Next Tweet et' butt prowide a way to open a br owser displaying the web page coresponding to URLs embedded in the rweers provide a way for users to view the Flicka plotos. Eg. you might add an additional Label or Canvas widget ou the GUI and display the "current" pluoto on it. Like for tweets. the makes comesponding to that "cument" photo should look different than other markers. hupomaur enabling srps. Yon need a twitter account Guttus twitter.com for this ass Once you've done that youneed to create register a Twitter app, Do that here 3. You need to be able to import oautlu2 module (python-oauth2) in order to properly connect to Twitter using the Oauth secure authorization protocol. There are two options for this (the first being far simpler for most people) This approach is easy and should work for everyone: the only "bad thing about itis that it doesnt really install the oauth2 and coller packa standard Python place where theyd be available for funare useby other Python programs you might write. d want to "properly penuaanently install the uwodule, download the zip available luere lese and follow the istallati that pa the lab MacLe cluoose this opti first option abov 4 You will also need a Flickr API key. You can get one legge, It is a quick process, and it's easy to use Flick'sAPI once you have a key Other notes: l. For searching Twitter, use (and modify) the sample Tritter code promided with Lecture 41 (April 28). 2 For searching Flickr. use (and modify) the sample Flickr code (that mill be)provided with Leenure 42 May omplete the Flickr part ill need to the PIL modmle. It ailable Anaconda. Properly installing PIL yourself be difficult. strongly urge Anaconda if you do the Flickr part of the 4. you sluould remove the center-ofmap marker from HW9 Q2. The only markers sliould be for retr ed tweets and photos. 5. For Twitter: study How to build a query" and "Query oper at hrggs deu twitter.com restgullicseurch Your prograan slaould support at least exact pluase searches and hashtag searches You should use both the authTwitter and (z modified versiow of searchTwitter functions faom 6 For Flickr: stady the ElskLAPI documentation Scoring breakdown (so you can plan how much you want to do) 3 points for GUI that enables fication locat and retriev tweets, display map proper location 1 point for comectly placing markers on the map and bein step though set point for properly constraining Twitter search by locat point for being able to open URL ontained in currently displa yed tweet point for retrieving Flickr plaotos for the specified location and top point for being able to display. step through retrieved Flicka photos

Explanation / Answer

import tkinter
from tkinter import *
import math
from urllib.request import urlopen, urlretrieve
from urllib.parse import urlencode
import json

# To use, see the last function in this file, startGUI().

# Given a string representing a location, return 2-element
# [latitude, longitude] list for that location
#
# See https://developers.google.com/maps/documentation/geocoding/
# for details
#
def geocodeAddress(addressString):

urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
adst = urlencode({'address': addressString})
url = urlbase + adst

resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['geometry']['location']
return (float(loc['lat']),float(loc['lng']))

#
# Google will also "reverse geocode." That is, you can provide a latitude and longitude and
# and Google will try to provide "human readable" information about that location.
#
# E. g. geocodeLatLng(41.6613, -91.5361)
#
# Again, see https://developers.google.com/maps/documentation/geocoding/
#
def geocodeLatLng(lat, lng):
urlbase = "http://maps.googleapis.com/maps/api/geocode/json?"
latLngstring = "{},{}".format(lat,lng)
adst = urlencode({'latlng': latLngstring})
url = urlbase+adst
resultFromGoogle = urlopen(url).read().decode('utf8')
jsonresult = json.loads(resultFromGoogle)
if (jsonresult['status'] != "OK"):
print("Status returned from geocoder *not* OK: {}".format(jsonresult['status']))
return
loc = jsonresult['results'][0]['addressFormat']
return loc


# Contruct a Google Static Maps API URL that specifies a map that is:
# - width-by-height in size (in pixels)
# - is centered at latitude lat and longitude long
# - is "zoomed" to the give Google Maps zoom level
#
# See https://developers.google.com/maps/documentation/static-maps/
#
# YOU WILL NEED TO MODIFY THIS TO BE ABLE TO
# 1) DISPLAY A PIN ON THE MAP
# 2) SPECIFY MAP TYPE - terrain vs road vs ...
#
def getMapUrl(width, height, lat, lng, zoom):
urlbase = "http://maps.google.com/maps/api/staticmap?"
parameter = "center={},{}&zoom={}&size={}x{}&format=gif".format(lat,lng,zoom,width,height)
return urlbase+parameter

# Retrieve a map image via Google Static Maps API:
# - centered at the location specified by global variable mapLocation
# - zoomed according to global variable zoomLevel (Google's zoom levels range from 0 to 21)
# - width and height equal to global variable mapSize
# Store the returned image in file name specified by global variable mapFileName
#
def retrieveMap():
lat, lng = geocodeAddress(mapLocation)
url = getMapUrl(mapSize, mapSize, lat, lng, zoomLevel)
urlretrieve(url, mapFileName)
return mapFileName

##########
# very basic GUI code

# Global variables used by GUI and map code
#

rootWindow = None
mapLabel = None

defaultLocation = "Mauna Kea, Hawaii"
mapLocation = defaultLocation
mapFileName = 'googlemap.gif'
mapSize = 400
zoomLevel = 9

def readEntryAndShowMap():
global mapLocation
global E
#### you should change this function to read from the location from an Entry widget
#### instead of using the default location
mapLocation = E.get()
showMap()
  
def showMap():
retrieveMap()
mapImage = tkinter.PhotoImage(file=mapFileName)
mapLabel.configure(image=mapImage)
# next line necessary to "prevent (image) from being garbage collected" - http://effbot.org/tkinterbook/label.htm
mapLabel.mapImage = mapImage
  
def initializeGUIetc():
global rootWindow
global mapLabel
global E

rootWindow = tkinter.Tk()
rootWindow.title("HW 10")

mainFrame = tkinter.Frame(rootWindow)
mainFrame.pack()

# until you add code, pressing this button won't change the map.
# you need to add an Entry widget that allows you to type in an address
# The click function should extract the location string from the Entry widget and create
# the appropriate map.

locationLabel = tkinter.Label(mainFrame, text="Enter Location.", bd = 1)
locationLabel.pack()

E = Entry(rootWindow, bd = 5)
E.pack()

readEntryAndShowMapButton = tkinter.Button(mainFrame, text="Show me the map!", command=readEntryAndShowMap)
readEntryAndShowMapButton.pack()

# we use a tkinter Label to display the map image

mapLabel = tkinter.Label(mainFrame, bd=2, relief=tkinter.FLAT)
mapLabel.pack()

def startGUI():
initializeGUIetc()
showMap()
rootWindow.mainloop()