implementation.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. # File Name: implementation.py
  2. # Modified Date: April 16, 2017
  3. # Description: This class does functionalities such as validation check, calculation and
  4. # it also interacts with users by displaying a result message as a popup window.
  5. # Method Level Comment: Python Convention (inside function)
  6. __author__ = "Inyoung Choung"
  7. import tkinter
  8. from tkinter import messagebox
  9. from impl_interface import ImplInterface
  10. # Impl class implements ImplInterface.
  11. class Impl(ImplInterface):
  12. # Here are the global variables that can be accessed throughout the class.
  13. global itemtype, brandN1, brandN2
  14. global price1, price2
  15. global weight1, weightT1, weight2, weightT2
  16. global discount1, discountT1, discount2, discountT2
  17. global newWeightForSecondItem
  18. global isEmpty
  19. global isFinalized
  20. global result
  21. global list
  22. global path
  23. def __init__(self, itemtype, brandN1, brandN2, price1, price2, weight1, weightT1,
  24. weight2, weightT2, discount1, discountT1, discount2, discountT2):
  25. """
  26. This method is a constructor that initializes parameters.
  27. :param itemtype:
  28. :param brandN1:
  29. :param brandN2:
  30. :param price1:
  31. :param price2:
  32. :param weight1:
  33. :param weightT1:
  34. :param weight2:
  35. :param weightT2:
  36. :param discount1:
  37. :param discountT1:
  38. :param discount2:
  39. :param discountT2:
  40. """
  41. # initialize values to the class variables.
  42. self.itemtype = itemtype
  43. self.brandN1 = brandN1
  44. self.brandN2 = brandN2
  45. self.price1 = price1
  46. self.price2 = price2
  47. self.weight1 = weight1
  48. self.weightT1 = weightT1
  49. self.weight2 = weight2
  50. self.weightT2 = weightT2
  51. self.discount1 = discount1
  52. self.discountT1 = discountT1
  53. self.discount2 = discount2
  54. self.discountT2 = discountT2
  55. # calls this function to validate any empty fields from users.
  56. self.validate_emptyfields()
  57. # after users values are accepted, do calculation based on the weight types of the two items.
  58. if self.weightT1 != self.weightT2:
  59. # if the weight types are different,
  60. # the second items should convert to the first item weight type.
  61. self.newWeightForSecondItem = self.convert(self.weightT1, self.weightT2, self.weight2)
  62. else:
  63. # both items have the same weight type.
  64. self.newWeightForSecondItem = self.weight2
  65. # do calculation on which item is cheaper.
  66. self.calculate()
  67. def validate_emptyfields(self):
  68. """
  69. This function checks any null values.
  70. :return:
  71. """
  72. # if there is any empty field
  73. if (self.itemtype is None or self.itemtype == "" or
  74. self.brandN1 is None or self.brandN1 == "" or
  75. self.brandN2 is None or self.brandN2 == "" or
  76. self.price1 is None or self.price1 == "" or
  77. self. price2 is None or self.price2 == "" or
  78. self.weight1 is None or self.weight1 == "" or
  79. self.weightT1 is None or self.weightT1 == "" or
  80. self. weight2 is None or self.weight2 == "" or
  81. self.weightT2 is None or self.weightT2 == "" or
  82. self.discount1 is None or self.discount1 == "" or
  83. self.discountT1 is None or self.discountT1 == "" or
  84. self.discount2 is None or self.discount2 == "" or
  85. self.discountT2 is None or self.discountT2 == ""):
  86. # if there is any empty field, initialize value; true to the variable.
  87. self.isEmpty = True
  88. # if there is any empty field, prompt a message to user.
  89. self.display_message(None)
  90. else:
  91. # if there is no any empty field, initialize value; false to the variable.
  92. self.isEmpty = False
  93. def convert(self, weightT1, weightT2, weight2):
  94. """
  95. This function converts the second item weight type to the first weight item type.
  96. :param weightT1:
  97. :param weightT2:
  98. :param weight2:
  99. :return: self.weight2
  100. """
  101. if weightT1 == "lb":
  102. if weightT2 == "kg":
  103. self.weight2 = float(weight2) * 2.20462
  104. elif weightT2 == "g":
  105. self.weight2 = float(weight2) * 0.002205
  106. elif weightT1 == "kg":
  107. if weightT2 == "lb":
  108. self.weight2 = float(weight2) * 0.453592
  109. elif weightT2 == "g":
  110. self.weight2 = float(weight2) * 0.001
  111. elif weightT1 == "g":
  112. if weightT2 == "kg":
  113. self.weight2 = float(weight2) * 1000
  114. elif weightT2 == "lb":
  115. self.weight2 = float(weight2) * 453.592
  116. # returns the converted second weight based on the first item weight type.
  117. return self.weight2
  118. def calculate(self):
  119. """
  120. This function calculates to see which item is cheaper by the unit weight.
  121. :return: self.result
  122. """
  123. # checks which discount type each first item has and calculates the price to the final price.
  124. if self.discountT1 == "percentage":
  125. finalPrice1 = float(float(self.price1) - (float(self.price1) * (float(self.discount1) * float(0.01))) / float(self.weight1))
  126. elif self.discountT1 == "dollar":
  127. finalPrice1 = float((float(self.price1) - float(self.discount1)) / float(self.weight1))
  128. # checks which discount type each second item has and calculates the price to the final price.
  129. if self.discountT2 == "percentage":
  130. finalPrice2 = float((float(self.price2) - (float(self.price2) * (float(self.discount2) * float(0.01)))) / float(self.newWeightForSecondItem))
  131. elif self.discountT2 == "dollar":
  132. finalPrice2 = float((float(self.price2) - (float(self.discount2))) / float(self.newWeightForSecondItem))
  133. # compare the final price of the two items.
  134. if finalPrice1 > finalPrice2:
  135. priceDiff = float(round(finalPrice1 - finalPrice2, 3))
  136. print(self.brandN1 + str(" is cheaper by "), priceDiff, str(" cents per unit weight "))
  137. self.result = str(self.brandN1 + str(" is cheaper by ") + str(priceDiff) + str(" cents per unit weight "))
  138. elif finalPrice1 < finalPrice2:
  139. priceDiff = float(round(finalPrice2 - finalPrice1, 3))
  140. print(self.brandN2 + str(" is cheaper by "), priceDiff, str(" cents per unit weight "))
  141. self.result = str(self.brandN2 + str(" is cheaper by ") + str(priceDiff) + str(" cents per unit weight "))
  142. else:
  143. self.result = str("The price is equal so get anything!")
  144. # once the calculation is done, initialize value; True to the variable.
  145. self.isFinalized = True
  146. # calls this function to display the popup message to the user.
  147. self.display_message(None)
  148. return self.result
  149. def get_result(self):
  150. """
  151. This function returns String; result.
  152. :return: self.result
  153. """
  154. return self.result
  155. def display_message(self, message):
  156. """
  157. This function is to check which message is to display to user based on boolean variables.
  158. :param message:
  159. :return: message
  160. """
  161. if (message is None):
  162. if self.isEmpty is True:
  163. # hide main window
  164. root = tkinter.Tk()
  165. root.withdraw()
  166. # show the error message to the user after validation.
  167. messagebox.showerror("Alert - Empty fields", "Please fill out all the forms.")
  168. # set False to isEmpty variable.
  169. self.isEmpty = False
  170. elif self.isFinalized is True:
  171. # hide main window.
  172. root = tkinter.Tk()
  173. root.withdraw()
  174. # show the result message to the user.
  175. messagebox.showinfo("Calculation Result", self.result)
  176. else:
  177. # hide main window.
  178. root = tkinter.Tk()
  179. root.withdraw()
  180. # This is for the pytest purpose and display the message that is passed from the parameter.
  181. messagebox.showinfo("Calculation Result", message)
  182. return message
  183. def sort(self, list):
  184. """
  185. This function gets list, sort it and returns that list.
  186. :param list:
  187. :return: list
  188. """
  189. # sort the list in the alphabetical order.
  190. list.sort()
  191. # print out the string and the list to console.
  192. print("This is a sorted brand_name list by the alphabetical order.")
  193. print(list)
  194. return list
  195. def writefile(self, path, stuff_to_print):
  196. """
  197. TFile I/O - prints a sorted list of grocery items.
  198. :param path:
  199. :param stuff_to_print:
  200. :return:
  201. """
  202. if path is None :
  203. # set a specific path
  204. self.path = "C:\In-young Choung\Computer Programming\Self Programming Files\grocerycalc\itemlist.txt"
  205. # write a file if it doesn't exist
  206. f = open(self.path, "w+")
  207. # write each item of the grocery list inside the opened file
  208. for i in stuff_to_print :
  209. f.write(i)
  210. else :
  211. self.path = path
  212. # write a file if it doesn't exist
  213. f = open(self.path, "w+")
  214. # write some texts inside the opened file
  215. f.write(stuff_to_print)
  216. def readfile(self):
  217. """
  218. read file that is created and pass filepath as a parameter.
  219. :return:
  220. """
  221. # open the file in the defined path and "r" read it
  222. f = open(self.path, "r")
  223. # mode is matched with 'r' (read)
  224. if f.mode == 'r':
  225. # use read function to read the entire file.
  226. contents = f.read()
  227. # print the file content in the console
  228. print("This is a list from reading a file.")
  229. # print the file content by one letter at a time
  230. for i in contents:
  231. print(i)
  232. else :
  233. print("wrong mode in readfile function.")