# File Name: implementation.py # Modified Date: April 16, 2017 # Description: This class does functionalities such as validation check, calculation and # it also interacts with users by displaying a result message as a popup window. # Method Level Comment: Python Convention (inside function) __author__ = "Inyoung Choung" import tkinter from tkinter import messagebox from impl_interface import ImplInterface # Impl class implements ImplInterface. class Impl(ImplInterface): # Here are the global variables that can be accessed throughout the class. global itemtype, brandN1, brandN2 global price1, price2 global weight1, weightT1, weight2, weightT2 global discount1, discountT1, discount2, discountT2 global newWeightForSecondItem global isEmpty global isFinalized global result global list global path def __init__(self, itemtype, brandN1, brandN2, price1, price2, weight1, weightT1, weight2, weightT2, discount1, discountT1, discount2, discountT2): """ This method is a constructor that initializes parameters. :param itemtype: :param brandN1: :param brandN2: :param price1: :param price2: :param weight1: :param weightT1: :param weight2: :param weightT2: :param discount1: :param discountT1: :param discount2: :param discountT2: """ # initialize values to the class variables. self.itemtype = itemtype self.brandN1 = brandN1 self.brandN2 = brandN2 self.price1 = price1 self.price2 = price2 self.weight1 = weight1 self.weightT1 = weightT1 self.weight2 = weight2 self.weightT2 = weightT2 self.discount1 = discount1 self.discountT1 = discountT1 self.discount2 = discount2 self.discountT2 = discountT2 # calls this function to validate any empty fields from users. self.validate_emptyfields() # after users values are accepted, do calculation based on the weight types of the two items. if self.weightT1 != self.weightT2: # if the weight types are different, # the second items should convert to the first item weight type. self.newWeightForSecondItem = self.convert(self.weightT1, self.weightT2, self.weight2) else: # both items have the same weight type. self.newWeightForSecondItem = self.weight2 # do calculation on which item is cheaper. self.calculate() def validate_emptyfields(self): """ This function checks any null values. :return: """ # if there is any empty field if (self.itemtype is None or self.itemtype == "" or self.brandN1 is None or self.brandN1 == "" or self.brandN2 is None or self.brandN2 == "" or self.price1 is None or self.price1 == "" or self. price2 is None or self.price2 == "" or self.weight1 is None or self.weight1 == "" or self.weightT1 is None or self.weightT1 == "" or self. weight2 is None or self.weight2 == "" or self.weightT2 is None or self.weightT2 == "" or self.discount1 is None or self.discount1 == "" or self.discountT1 is None or self.discountT1 == "" or self.discount2 is None or self.discount2 == "" or self.discountT2 is None or self.discountT2 == ""): # if there is any empty field, initialize value; true to the variable. self.isEmpty = True # if there is any empty field, prompt a message to user. self.display_message(None) else: # if there is no any empty field, initialize value; false to the variable. self.isEmpty = False def convert(self, weightT1, weightT2, weight2): """ This function converts the second item weight type to the first weight item type. :param weightT1: :param weightT2: :param weight2: :return: self.weight2 """ if weightT1 == "lb": if weightT2 == "kg": self.weight2 = float(weight2) * 2.20462 elif weightT2 == "g": self.weight2 = float(weight2) * 0.002205 elif weightT1 == "kg": if weightT2 == "lb": self.weight2 = float(weight2) * 0.453592 elif weightT2 == "g": self.weight2 = float(weight2) * 0.001 elif weightT1 == "g": if weightT2 == "kg": self.weight2 = float(weight2) * 1000 elif weightT2 == "lb": self.weight2 = float(weight2) * 453.592 # returns the converted second weight based on the first item weight type. return self.weight2 def calculate(self): """ This function calculates to see which item is cheaper by the unit weight. :return: self.result """ # checks which discount type each first item has and calculates the price to the final price. if self.discountT1 == "percentage": finalPrice1 = float(float(self.price1) - (float(self.price1) * (float(self.discount1) * float(0.01))) / float(self.weight1)) elif self.discountT1 == "dollar": finalPrice1 = float((float(self.price1) - float(self.discount1)) / float(self.weight1)) # checks which discount type each second item has and calculates the price to the final price. if self.discountT2 == "percentage": finalPrice2 = float((float(self.price2) - (float(self.price2) * (float(self.discount2) * float(0.01)))) / float(self.newWeightForSecondItem)) elif self.discountT2 == "dollar": finalPrice2 = float((float(self.price2) - (float(self.discount2))) / float(self.newWeightForSecondItem)) # compare the final price of the two items. if finalPrice1 > finalPrice2: priceDiff = float(round(finalPrice1 - finalPrice2, 3)) print(self.brandN1 + str(" is cheaper by "), priceDiff, str(" cents per unit weight ")) self.result = str(self.brandN1 + str(" is cheaper by ") + str(priceDiff) + str(" cents per unit weight ")) elif finalPrice1 < finalPrice2: priceDiff = float(round(finalPrice2 - finalPrice1, 3)) print(self.brandN2 + str(" is cheaper by "), priceDiff, str(" cents per unit weight ")) self.result = str(self.brandN2 + str(" is cheaper by ") + str(priceDiff) + str(" cents per unit weight ")) else: self.result = str("The price is equal so get anything!") # once the calculation is done, initialize value; True to the variable. self.isFinalized = True # calls this function to display the popup message to the user. self.display_message(None) return self.result def get_result(self): """ This function returns String; result. :return: self.result """ return self.result def display_message(self, message): """ This function is to check which message is to display to user based on boolean variables. :param message: :return: message """ if (message is None): if self.isEmpty is True: # hide main window root = tkinter.Tk() root.withdraw() # show the error message to the user after validation. messagebox.showerror("Alert - Empty fields", "Please fill out all the forms.") # set False to isEmpty variable. self.isEmpty = False elif self.isFinalized is True: # hide main window. root = tkinter.Tk() root.withdraw() # show the result message to the user. messagebox.showinfo("Calculation Result", self.result) else: # hide main window. root = tkinter.Tk() root.withdraw() # This is for the pytest purpose and display the message that is passed from the parameter. messagebox.showinfo("Calculation Result", message) return message def sort(self, list): """ This function gets list, sort it and returns that list. :param list: :return: list """ # sort the list in the alphabetical order. list.sort() # print out the string and the list to console. print("This is a sorted brand_name list by the alphabetical order.") print(list) return list def writefile(self, path, stuff_to_print): """ TFile I/O - prints a sorted list of grocery items. :param path: :param stuff_to_print: :return: """ if path is None : # set a specific path self.path = "C:\In-young Choung\Computer Programming\Self Programming Files\grocerycalc\itemlist.txt" # write a file if it doesn't exist f = open(self.path, "w+") # write each item of the grocery list inside the opened file for i in stuff_to_print : f.write(i) else : self.path = path # write a file if it doesn't exist f = open(self.path, "w+") # write some texts inside the opened file f.write(stuff_to_print) def readfile(self): """ read file that is created and pass filepath as a parameter. :return: """ # open the file in the defined path and "r" read it f = open(self.path, "r") # mode is matched with 'r' (read) if f.mode == 'r': # use read function to read the entire file. contents = f.read() # print the file content in the console print("This is a list from reading a file.") # print the file content by one letter at a time for i in contents: print(i) else : print("wrong mode in readfile function.")