123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- # File Name: app.py
- # Modified Date: March 24, 2017
- # Description: This python file contains database configuration and creates database tables and fields using flask_sqlalchemy.
- # Users' values passed from Javascript are inserted into the database table.
- # It also has mapping request to interact with specific html files and
- # it reads a file of itemlist.text and prints out to the console.
- __author__ = "Inyoung Choung"
- import tkinter
- from tkinter import messagebox
- from flask_sqlalchemy import SQLAlchemy
- from flask import Flask, render_template, request
- # passing the whole app code to Flask
- app = Flask(__name__)
- # Configuration for Database ORM - database name: grocery app, user: groceryadmin, password: VKov2q3XTtqj6w9o
- app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://groceryadmin:VKov2q3XTtqj6w9o@localhost/groceryapp'
- app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
- # Database instantiation
- db = SQLAlchemy(app)
- # database ORM calc table - 3 columns
- class Calc(db.Model):
- __tablename__="calc"
- # database fields
- id = db.Column(db.Integer, primary_key=True)
- result = db.Column(db.String(64))
- timestampe = db.Column(db.TIMESTAMP)
- # adding constraints to delete all data in Item when calc is deleted.
- item = db.relationship('Item', backref='calc', cascade='all, delete-orphan', lazy='dynamic')
- # database ORM item table - 9 columns
- class Item(db.Model):
- __tablename__ = "items"
- # database fields
- id = db.Column(db.Integer, primary_key=True)
- item_type = db.Column(db.String(64))
- brand_name = db.Column(db.String(64))
- price = db.Column(db.DECIMAL)
- weight = db.Column(db.DECIMAL)
- weight_type = db.Column(db.String(5))
- discount = db.Column(db.DECIMAL)
- discount_type = db.Column(db.String(20))
- calc_id = db.Column(db.Integer, db.ForeignKey(Calc.id))
- # create all the tables defined as classes
- # db.create_all()
- # mapping request to URLs
- @app.route('/', methods = ['GET', 'POST'])
- def index():
- if request.method == 'GET':
- # renders to html file
- return render_template('index.html')
- def convert(weightT1, weightT2, weight2):
- if weightT1 == "lb":
- if weightT2 == "kg":
- weight2 = float(weight2) * 2.20462
- elif weightT2 == "g":
- weight2 = float(weight2) * 0.002205
- elif weightT1 == "kg":
- if weightT2 == "lb":
- weight2 = float(weight2) * 0.453592
- elif weightT2 == "g":
- weight2 = float(weight2) * 0.001
- elif weightT1 == "g":
- if weightT2 == "kg":
- weight2 = float(weight2) * 1000
- elif weightT2 == "lb":
- weight2 = float(weight2) * 453.592
- return weight2
- def alert_message(message_arg):
- if message_arg is None:
- message = str("Please fill out all the forms.")
- else:
- message = message_arg
- return message
- global newWeightForSecondItem
- # end point where python gets user data from javascript
- @app.route('/calculate', methods = ['GET'])
- def calculate():
- # get value from html
- itemtype = (request.args.get('param1'))
- brandN1 = (request.args.get('param2'))
- brandN2 = (request.args.get('param3'))
- price1 = (request.args.get('param4'))
- price2 = (request.args.get('param5'))
- weight1 = (request.args.get('param6'))
- weightT1 = (request.args.get('param7'))
- weight2 = (request.args.get('param8'))
- weightT2 = (request.args.get('param9'))
- discount1 = (request.args.get('param10'))
- discountT1 = (request.args.get('param11'))
- discount2 = (request.args.get('param12'))
- discountT2 = (request.args.get('param13'))
- if (itemtype is None or itemtype == "" or
- brandN1 is None or brandN1 == "" or
- brandN2 is None or brandN2 == "" or
- price1 is None or price1 == "" or
- price2 is None or price2 == "" or
- weight1 is None or weight1 == "" or
- weightT1 is None or weightT1 == "" or
- weight2 is None or weight2 == "" or
- weightT2 is None or weightT2 == "" or
- discount1 is None or discount1 == "" or
- discountT1 is None or discountT1 == "" or
- discount2 is None or discount2 == "" or
- discountT2 is None or discountT2 == ""):
- # hide main window
- root = tkinter.Tk()
- root.withdraw()
- messagebox.showerror( "Alert - Empty fields", alert_message("Please fill out all the forms."))
- # after users values are accepted, do calculation.
- if weightT1 != weightT2:
- newWeightForSecondItem = convert(weightT1, weightT2, weight2)
- # both items have the same weight type from this point
- else:
- newWeightForSecondItem = weight2
- if discountT1 == "percentage":
- finalPrice1 = float((float(price1) - (float(price1) * (float(discount1) * float(0.01)))) / float(weight1))
- elif discountT1 == "dollar":
- finalPrice1 = float((float(price1) - float(discount1)) / float(weight1))
- if discountT2 == "percentage":
- finalPrice2 = float((float(price2) - (float(price2) * (float(discount2) * float(0.01)))) / float(newWeightForSecondItem))
- elif discountT2 == "dollar":
- finalPrice2 = float((float(price2) - (float(discount2))) / float(newWeightForSecondItem))
- if finalPrice1 > finalPrice2:
- priceDiff = round(float(finalPrice1 - finalPrice2), 3)
- print(brandN1 + str(" is cheaper by "), priceDiff)
- result = str(brandN1 + str(" is cheaper by ") + str(priceDiff) + str(" cents per unit weight "))
- elif finalPrice1 < finalPrice2:
- priceDiff = round(float(finalPrice2 - finalPrice1), 3)
- print(brandN2 + str(" is cheaper by "), priceDiff)
- result = str(brandN2 + str(" is cheaper by ") + str(priceDiff) + str(" cents per unit weight "))
- else:
- result = str("The price is equal so get anything!")
- # hide main window
- root = tkinter.Tk()
- root.withdraw()
- messagebox.showinfo("Calculation Result", result)
- try:
- # define array variables to be ready to match with db columns
- brand_names = [brandN1, brandN2]
- prices = [price1, price2]
- weights = [weight1, weight2]
- weight_types = [weightT1, weightT2]
- discounts = [discount1, discount2]
- discount_types = [discountT1, discountT2]
- # iteration variable for loop
- i = 0
- # loop twice to save two compared items into database
- for i in range(0, 2):
- item = Item(item_type = itemtype, brand_name = brand_names[i], price =prices[i],
- weight=weights[i] , weight_type = weight_types[i], discount = discounts[i] ,
- discount_type = discount_types[i])
- # insert a new row into the database
- db.session.add(item)
- # write it to db disk once the loop is done
- db.session.commit()
- return result
- # catch the exception and print it
- except ValueError:
- print(ValueError)
- print("failed to create new row")
- return -1
- # File I/O - prints a list of grocery items
- def writefile(path, word):
- # open a file for writing and create it if it doesn't exist.
- if path is None:
- # set a specific path
- filepath = "C:\In-young Choung\Computer Programming\Self Programming Files\grocerycalc\itemlist.txt"
- # output a file if it doesn't exist
- f = open(filepath, "w+")
- # write some texts inside the opened file
- f.write("chicken, ")
- f.write("milk")
- readfile(filepath)
- else: # when the path is specified
- filepath= path
- # output a file if it doesn't exist
- f = open(filepath, "w+")
- # write text that is passed as a paramter in the method
- f.write(word)
- # read file that is created and pass filepath as a parameter
- def readfile(filepath):
- # open the file in the defined path and "r" read it
- f = open(filepath, "r")
- if f.mode == 'r':
- # use read function to read the entire file.
- contents = f.read()
- #print the file content in the console
- print(contents)
- # main method
- if __name__ == '__main__':
- app.debug = True
- # app.debug = False
- writefile(None, None)
- app.run()
|