I've created the following app in Python 3.5. The app uses pyowm and will take a location and return weather information. I've also built a GUI with tkinter for it.Keen to find out some tips to improve my coding style.import tkinter as tkimport pyowmimport datetime, timeclass WeatherInfo(tk.Tk):    def __init__(self):        tk.Tk.__init__(self)        self.wm_title('Weather')        self.temp = tk.StringVar(self,value='')        self.humid = tk.StringVar(self,value='')        self.status = tk.StringVar(self,value='')        self.sunrise = tk.StringVar(self,value='')        self.sunset = tk.StringVar(self,value='')        self.ld = tk.StringVar(self,value = '')        self.ln = tk.StringVar(self,value = '')        self.ask = tk.LabelFrame(self, text ='Location')        self.ask.pack(fill='both',expand='yes')        self.kw_label = tk.Label(self.ask, text ='Get weather in:')        self.kw_label.pack(side = tk.LEFT)        self.kw = tk.Entry(self.ask)        self.kw.pack(side = tk.RIGHT)        self.rb = tk.Button(self, text='Go', command = self.search)        self.rb.pack()        self.owm = pyowm.OWM('*CENSORED*')        self.output = tk.LabelFrame(self, text ='Information')        self.output.pack(fill='both',expand='yes')        tk.Label(self.output, textvariable = self.temp).pack()        tk.Label(self.output, textvariable=self.humid).pack()        tk.Label(self.output, textvariable=self.status).pack()        tk.Label(self.output, textvariable=self.sunrise).pack()        tk.Label(self.output, textvariable=self.sunset).pack()        tk.Label(self.output, textvariable=self.ld).pack()        tk.Label(self.output, textvariable=self.ln).pack()        button = tk.Button(master=self, text='Quit', command=self._quit)        button.pack(side=tk.BOTTOM)    def search(self):        obs = self.owm.weather_at_place(self.kw.get())        try:            w = obs.get_weather()            self.temp.set('Temperature: ' +str(round(w.get_temperature()['temp'] - 273.15,0))+ ' C')            self.humid.set('Humidity: '+str(w.get_humidity())+ '%')            self.status.set('Status: ' + w.get_status())            self.sunrise.set('Sunrise at '+datetime.datetime.fromtimestamp(w.get_sunrise_time()).strftime('%H:%M:%S'))            self.sunset.set('Sunset at '+datetime.datetime.fromtimestamp(w.get_sunset_time()).strftime('%H:%M:%S'))            self.ld.set('Day length: '+str(round((w.get_sunset_time() - w.get_sunrise_time()) / 3600,1))+' h')            self.ln.set('Night length: '+str(round(24 - (w.get_sunset_time() - w.get_sunrise_time()) / 3600,1))+' h')        except:            self.temp.set('Pick a city to display weather.')    def _quit(self):        self.quit()        self.destroy()app = WeatherInfo()app.mainloop() 
Create a weather app in Python
python;python 3.x;tkinter
Your code has a few different responsibilities, most of which are currently in the search function:Setting up the GUIRetrieving the weather reportParsing the relevant data out of that reportDisplaying the resultEach of these deserves their own function. I would also abstract the format itself away into a constant of the class. This allows looping over the different keys to build the objects instead of having to do it manually. I used a collections.OrderedDict to preserve the order of them.These template strings are:class WeatherInfo(tk.Tk):    templates = OrderedDict([        ('temp', 'Temperature: {temp:.1f} C'),        ('humid', 'Humidity: {humid}%'),        ('status', 'Status: {status}'),        ('sunrise', 'Sunrise at {sunrise:%H:%M:%S}'),        ('sunset', 'Sunset at {sunset:%H:%M:%S}'),        ('day_length', 'Day length: {day_length:.1f} h'),        ('night_length', 'Night length: {night_length:.1f} h')])Note that you can already define the format for the date in there and also the rounding for floats.This allows doing this in __init__:def __init__(self):    ...    self.tk_info = {key: tk.StringVar(        self, value='') for key in WeatherInfo.templates}    ...    self.labels = []    for key in WeatherInfo.templates:        self.labels.append(            tk.Label(self.output, textvariable=self.tk_info[key]).pack())    ...search should just be concerned with getting the result from the web, catching an error if needed. Here you should notice that you should never have a bare except. It will also catch e.g. the user pressing CTRL-C to abort the program. Always use at least except Exception which will catch almost everything (and not some special exceptions like CTRL-C). Here you can be more specific, because the code will throw a AttributeError if unsuccessful:def search(self):    obs = self.owm.weather_at_place(self.kw.get())    try:        return json.loads(obs.get_weather().to_JSON())    except AttributeError:        self.tk_info['temp'].set('Pick a city to display weather.')Note that I am using the json format here, just because I think it is more intuitive to work with. But you can also use the get_* functions in parse.Speaking of which: I would add a parse function that takes the result of obs.get_weather and does all the conversions/calculations. It returns a dictionary with the raw values we want to put in the template:def parse(self, w):    parsed_weather = {'temp': round(w['temperature']['temp'] - 273.15, 0),                      'humid': w['humidity'],                      'status': w['status'],                      'sunrise': datetime.fromtimestamp(w['sunrise_time']),                      'sunset': datetime.fromtimestamp(w['sunset_time']),                      'day_length': round((w['sunset_time'] - w['sunrise_time']) / 3600, 1),                      'night_length': round(24 - (w['sunset_time'] - w['sunrise_time']) / 3600, 1)}    return parsed_weatherI also used from datetime import datetime in the header to get rid of one level of redundant naming.Then I would define a update function, which updates all the labels to the correct wording. Here it comes in handy that we already have the template strings defined and have a dictionary of the values we want to put in there!def update(self, report):    for key, template in WeatherInfo.templates.items():        self.tk_info[key].set(template.format(**report))The whole thing comes together in the main function (for lack of a better word):def main(self):    report = self.search()    if report:        self.update(self.parse(report))Of course, this main function has to be linked to the Go button instead of search now.Finally, I would guard the execution of the app with a if __name__ == __main__ clause to allow importing of your module without executing it.Final code:import tkinter as tkimport pyowmimport timeimport jsonfrom datetime import datetimefrom collections import OrderedDictclass WeatherInfo(tk.Tk):    templates = OrderedDict([        ('temp', 'Temperature: {temp:.1f} C'),        ('humid', 'Humidity: {humid}%'),        ('status', 'Status: {status}'),        ('sunrise', 'Sunrise at {sunrise:%H:%M:%S}'),        ('sunset', 'Sunset at {sunset:%H:%M:%S}'),        ('day_length', 'Day length: {day_length:.1f} h'),        ('night_length', 'Night length: {night_length:.1f} h')])    def __init__(self):        tk.Tk.__init__(self)        self.wm_title('Weather')        self.tk_info = {key: tk.StringVar(            self, value='') for key in WeatherInfo.templates}        self.ask = tk.LabelFrame(self, text='Location')        self.ask.pack(fill='both', expand='yes')        self.kw_label = tk.Label(self.ask, text='City:')        self.kw_label.pack(side=tk.LEFT)        self.kw = tk.Entry(self.ask)        self.kw.pack(side=tk.LEFT)        self.rb = tk.Button(self.ask, text='Go', command=self.main)        self.rb.pack(side=tk.RIGHT)        self.owm = pyowm.OWM('*CENSORED*')        self.output = tk.LabelFrame(self, text='Information')        self.output.pack(fill='both', expand='yes')        self.labels = []        for key in WeatherInfo.templates:            self.labels.append(                tk.Label(self.output, textvariable=self.tk_info[key]).pack())        button = tk.Button(master=self, text='Quit', command=self._quit)        button.pack(side=tk.BOTTOM)    def search(self):        obs = self.owm.weather_at_place(self.kw.get())        try:            return json.loads(obs.get_weather().to_JSON())        except AttributeError:            self.tk_info['temp'].set('Pick a city to display weather.')    def parse(self, w):        parsed_weather = {'temp': w['temperature']['temp'] - 273.15,                          'humid': w['humidity'],                          'status': w['status'],                          'sunrise': datetime.fromtimestamp(w['sunrise_time']),                          'sunset': datetime.fromtimestamp(w['sunset_time']),                          'day_length': (w['sunset_time'] - w['sunrise_time']) / 3600,                          'night_length': 24 - (w['sunset_time'] - w['sunrise_time']) / 3600}        return parsed_weather    def update(self, report):        for key, template in WeatherInfo.templates.items():            self.tk_info[key].set(template.format(**report))    def main(self):        report = self.search()        if report:            self.update(self.parse(report))    def _quit(self):        self.quit()        self.destroy()if __name__ == __main__:    app = WeatherInfo()    app.mainloop()