You are on page 1of 12

turn 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 tk

import pyowm

import datetime, time

class 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()

import json

# Repeatedly prompt for input until an integer is entered.

def inputInt(prompt):

while True:
try:

answer = int(input(prompt))

except ValueError:

print('Please enter a number.')

continue

break

return answer

# Repeatedly prompt for input until something (not whitespace) is entered.

def inputSomething(prompt):

answer = input(prompt)

while not answer.strip():

answer = input('Please enter a non-whitespace value: ')

return answer

# Open "data.txt" in write mode and write the data to it in JSON format.

def saveChanges(dataList):

f = open('data.txt', 'w')

json.dump(dataList, f, indent=4)

f.close()
# If the file does not exist or does not contain JSON data, set "data" to an empty list instead.

try:

f = open('data.txt', 'r')

data = json.load(f)

f.close()

except (FileNotFoundError, ValueError):

data = []

# Print welcome message, then enter the endless loop which prompts the user for a choice.

print('Welcome to the Food Quiz Admin Program.')

while True:

print('Choose [a]dd, [l]ist, [s]earch, [v]iew, [d]elete or [q]uit.')

choice = input('> ')

if choice == 'a':

print('Enter details for new menu item.')

#Create new item and prompt for values

item = {}

item['name'] = inputSomething('Name: ')

item['calories'] = inputInt('Calories: ')

item['fat'] = inputInt('Fat: ')

item['protien'] = inputInt('Protien: ')


item['carbohydrates'] = inputInt('Carbohydrates: ')

item['sodium'] = inputInt('Sodium: ')

item['cholesterol'] = inputInt('Cholesterol: ')

#Add item to data list and save changes

data.append(item)

saveChanges(data)

elif choice == 'l':

#Loop though and list the current menu items

for i, item in enumerate(data):

print(i, ': ', item)

elif choice == 's':

#Prompt for search term and convert to lowercase

search = inputSomething('Search items by name: ').lower()

#Loop through data and print items with search term in name

for i, item in enumerate(data):

if search in item['name'].lower():

print(i, ': ', item)


elif choice == 'v':

while True:

#Try to print item by index, reprompt if index is not valid

try:

indexItem = data[inputInt('Enter index of item to view: ')]

print('{name}, Calories: {calories}, Fat: {fat} g, Protien: {protien} g, Carbohydrates:


{carbohydrates} g, Cholesterol: {cholesterol} mg, Sodium: {sodium} mg'.format(**indexItem))

except IndexError:

print('Invalid index. Please enter the index of an existing item.')

continue

break

elif choice == 'd':

while True:

#Try to delete item by index, reprompt if index is not valid

try:

del data[inputInt(prompt)]

except IndexError:

print('Invalid index. Please enter the index of an existing item.')

continue
break

saveChanges(data)

elif choice == 'q':

# Quit the program

print('Goodbye!')

break

else:

# Print 'invalid choice' message

print('Invalid choice.')

GUI:

import tkinter

import tkinter.messagebox

import tkinter.font

import json

import random

class ProgramGUI:
def __init__(self):

#Create main window

self.main = tkinter.Tk()

self.main.title('Food Quiz!')

self.main.geometry('450x225')

self.main.configure(bg='#5c9ead')

self.font1 = tkinter.font.Font(family='Helvetica', size=18, weight='bold')

self.font2 = tkinter.font.Font(family='Courier', size=14, weight='bold')

#Load data from data.txt, show error message & terminate if file does not exist or is invalid

try:

self.__f = open('data.txt', 'r')

self.data = json.load(self.__f)

self.__f.close()

except (FileNotFoundError, ValueError):

tkinter.messagebox.showerror('Oops!', 'Missing/Invalid file.')

self.main.destroy()

return

#Define components, initiliase score and label variables

self.components = ['calories', 'fat', 'cholesterol', 'sodium', 'carbohydrates', 'protien']

self.qsAsked = 0

self.qsCorrect = 0
self.name1 = tkinter.StringVar()

self.name2 = tkinter.StringVar()

self.componentLab = tkinter.StringVar()

#Create frames

self.nameBox = tkinter.Frame(self.main, bg='#5c9ead')

self.questionBox = tkinter.Frame(self.main, bg='#5c9ead')

self.buttonBox = tkinter.Frame(self.main, bg='#5c9ead')

#Create buttons and labels

tkinter.Label(self.nameBox, textvariable=self.name1, font=self.font1, bg='#5c9ead',


fg='#EFBC9B').pack(side='left')

tkinter.Label(self.nameBox, text='vs', font=self.font2, bg='#5c9ead', fg='#fffdf7').pack(side='left')

tkinter.Label(self.nameBox, textvariable=self.name2, font=self.font1, bg='#5c9ead',


fg='#EFBC9B').pack(side='left')

tkinter.Label(self.questionBox, text='Which one has more...', font=self.font2, bg='#5c9ead',


fg='#fffdf7').pack()

tkinter.Label(self.questionBox, textvariable=self.componentLab, font=self.font1, bg='#5c9ead',


fg='#EFBC9B').pack()

tkinter.Button(self.buttonBox, textvariable=self.name1, font=self.font2, bg='#EFBC9B', fg='#FFFDF7',


command=lambda: self.checkAnswer('left')).pack(side='left')

tkinter.Button(self.buttonBox, text='Roughly Equal', font=self.font2, bg='#EFBC9B', fg='#FFFDF7',


command=lambda: self.checkAnswer('middle')).pack(side='left', padx=5)

tkinter.Button(self.buttonBox, textvariable=self.name2, font=self.font2, bg='#EFBC9B',


fg='#FFFDF7',command=lambda: self.checkAnswer('right')).pack(side='left')

self.nameBox.pack(pady=10)

self.questionBox.pack(pady=10)
self.buttonBox.pack(pady=20)

#Show first question

self.showQuestion()

#Start main loop

tkinter.mainloop()

def showQuestion(self):

#Create/update question attributes

self.items = random.sample(self.data, 2)

self.component = random.choice(self.components)

#Update labels

self.name1.set(self.items[0].get('name'))

self.name2.set(self.items[1].get('name'))

self.componentLab.set(self.component)

def checkAnswer(self, clickedButton):

#Update question counter and get values to compare

self.qsAsked += 1

self.val1 = self.items[0].get(self.component)

self.val2 = self.items[1].get(self.component)

#Define left button check (left > right), right button check (right > left) and middle button check
(both values are within 10% of each other, assuming val1 is > 0)
self.buttons = {'left': self.val1 > self.val2, 'right': self.val2 > self.val1, 'middle': self.val1 * 10 / 11 <=
self.val2 <= self.val1 * 11 / 10}

#Select check, update correct counter and display appropriate message

if self.buttons.get(clickedButton):

self.qsCorrect +=1

self.scoreMsg = 'Your score so far is ' + str(self.qsCorrect) + '/' + str(self.qsAsked)

tkinter.messagebox.showinfo('Correct!', 'You got it right. Your score so far is ' + str(self.qsCorrect) +


'/' + str(self.qsAsked))

else:

tkinter.messagebox.showerror('Incorrect!', 'You got it wrong. Your score so far is ' +


str(self.qsCorrect) + '/' + str(self.qsAsked))

#Generate new question

self.showQuestion()

# Create an object of the ProgramGUI class to begin the program.

gui = ProgramGUI()

You might also like