1 #Weather Forecast
2 import tkinter, requests
3 from tkinter import BOTH, IntVar
4 from PIL import ImageTk, Image
5 from io import BytesIO
6
7 #Define window
8 root = tkinter.Tk()
9 root.title('Weather Forecast')
10 root.iconbitmap('weather.ico')
11 root.geometry('400x400')
12 root.resizable(0,0)
13
14 #Define fonts and colors
15 1 sky_color = "#76c3ef"
16 grass_color = "#aad207"
17
18 E output_color = "#dcf0fb"
input_color = "#ecf2ae" ~ size Font
19 large_font = ('SimSun', 14)
20 small_font = ('Simsun', 10)
21
22 #Define functions
23 def search():
24 """Use open ewather api to look up current weather conditions given a city/ city,
country"""
25 global response
26
27 #Get API response
28 #URL and my api key....USE YOUR OWN API KEY!
29 url = 'https://api.openweathermap.org/data/2.5/weather'
30 api_key = '6da92ea5e09090fa9c8a08e08eb30284' #USE YOUR OWN API KEY
31
32 #Search by the appropriate query, either city name or zip
33 if search_method.get() == 1: radio button &
->
34 querystring = {"q":city_entry.get(), 'appid':api_key, 'units':'imperial'}
35 elif search_method.get() == 2:
36 querystring = {"zip":city_entry.get(), 'appid':api_key, 'units':'imperial'}
37
38 #Call API
39 response = requests.request("GET", url, params=querystring)
40 response = response.json()
List
edictionary
41
42 #Example response return ↑ ediction any
43 '''{'coord': {'lon': -71.06, 'lat': 42.36}, 'weather': [{'id': 500, 'main': 'Rain',
'description': 'light rain', 'icon': '10d'}], 'base': 'stations',
44 'main': {'temp': 298.88, 'feels_like': 302.56, 'temp_min': 298.15, 'temp_max':
299.82, 'pressure': 1010, 'humidity': 85}, 'visibility': 10000,
45 'wind': {'speed': 2.24, 'deg': 151, 'gust': 4.47}, 'rain': {'1h': 0.25}, 'clouds':
{'all': 82}, 'dt': 1596407271, 'sys': {'type': 3, 'id': 2005683,
46 'country': 'US', 'sunrise': 1596361095, 'sunset': 1596412955}, 'timezone': -14400,
'id': 4930956, 'name': 'Boston', 'cod': 200}'''
47
48 get_weather()
↳
49 get_icon()
50
51
52 def get_weather():
53 """Grab information from API response and update our weather labels."""
54 #Gather the data to be used from the API response
55 city_name = response['name']
56 city_lat = str(response['coord']['lat'])
57 city_lon = str(response['coord']['lon'])
58 Index[0]
59 main_weather = response['weather'][0]['main']
60 description = response['weather'][0]['description']
61
62 temp = str(response['main']['temp'])
63 feels_like = str(response['main']['feels_like'])
64 temp_min = str(response['main']['temp_min'])
65 temp_max = str(response['main']['temp_max'])
66 humidity = str(response['main']['humidity'])
67
68 #Update output lables
69 ⑦ city_info_label.config(text=city_name + "(" + city_lat + ", " + city_lon + ")",
font=large_font, bg=output_color)
70 ② weather_label.config(text="Weather: " + main_weather + ", " + description,
font=small_font, bg=output_color)
71 ③ temp_label.config(text='Temperature: ' + temp + " F", font=small_font,
bg=output_color)
72 ⑭ feels_label.config(text="Feels Like: " + feels_like + " F", font=small_font,
bg=output_color)
73 ⑤ temp_min_label.config(text="Min Temperature: " + temp_min + " F", font=small_font,
bg=output_color)
74 temp_max_label.config(text="Max Temperature: " + temp_max + " F", font=small_font,
⑧ bg=output_color)
75 humidity_label.config(text="Humidity: " + humidity, font=small_font, bg=output_color)
76
77
78 def get_icon():
79 """Get the appropriate weather icon from API response"""
80 global img
~IdexcOT
81
82 #Get the icon id from API response.
83 icon_id = response['weather'][0]['icon']
84 I
85 #Get the icon from the correct webiste A
86 url = 'http://openweathermap.org/img/wn/{icon}.png'.format(icon=icon_id)
87
88 #Make a request at the url to download the icon; stream=True automatically dl
89 icon_response = requests.get(url, stream=True)
90
91 #Turn into a form tkinter/python can use
92 - img_data = icon_response.content
93 img = ImageTk.PhotoImage(Image.open(BytesIO(img_data)))
M
94 I
95 #Update label
96 photo_label.config(image=img)
<Image "Photo"
97 ↳ Te Label =
98
99 #Define layout
100 #Create frames
101 sky_frame = tkinter.Frame(root, bg=sky_color, height=250)
102 grass_frame = tkinter.Frame(root, bg=grass_color)
103 sky_frame.pack(fill=BOTH, expand=True)
104 grass_frame.pack(fill=BOTH, expand=True)
105
106 output_frame = tkinter.LabelFrame(sky_frame, bg=output_color, width=325, height=225)
107 input_frame = tkinter.LabelFrame(grass_frame, bg=input_color, width=325)
108
109
110
111
output_frame.pack(pady=30)
output_frame.pack_propagate(0)
input_frame.pack(pady=15) -
donous width , height
/
reframe
112 #Output frame layout
113 city_info_label = tkinter.Label(output_frame, bg=output_color)
i
114 weather_label = tkinter.Label(output_frame, bg=output_color)
115 temp_label = tkinter.Label(output_frame, bg=output_color)
116 feels_label = tkinter.Label(output_frame, bg=output_color)
117 temp_min_label = tkinter.Label(output_frame, bg=output_color)
118 temp_max_label = tkinter.Label(output_frame, bg=output_color)
119 humidity_label = tkinter.Label(output_frame, bg=output_color)
120 photo_label = tkinter.Label(output_frame, bg=output_color)
121
122 city_info_label.pack(pady=8)
123 weather_label.pack()
124 temp_label.pack()
125 feels_label.pack()
126 temp_min_label.pack()
127 temp_max_label.pack()
128 humidity_label.pack()
129 photo_label.pack(pady=8)
130
131 #Input frame layout
132 #Create input frame buttson and entry
⑧
133 city_entry = tkinter.Entry(input_frame, width=20, font=large_font)
134 submit_button = tkinter.Button(input_frame, text='Submit', font=large_font,
bg=input_color, command=search)
-> define parameter
135
136 search_method = IntVar()
137 search_method.set(1)
138 ③ search_city = tkinter.Radiobutton(input_frame, text='Search by city name',
variable=search_method, value=1, font=small_font, bg=input_color)
139 ⑭ search_zip = tkinter.Radiobutton(input_frame, text="Search by zipcode",
variable=search_method, value=2, font=small_font, bg=input_color)
140
141 city_entry.grid(row=0, column=0, padx=10, pady=(10,0))
142 submit_button.grid(row=0, column=1, padx=10, pady=(10,0))
143 search_city.grid(row=1, column=0, pady=2)
144 search_zip.grid(row=1, column=1, padx=5, pady=2)
145
146 #Run root window's main loop
147 root.mainloop()
525
frame w
=
% -
* .....
1
-
Labelfsame * H =
225
-
...
frame *
* -Button
Label
frame
radio
↓
. Button
↳
Entry