diff --git a/FeatureEngineering/DB_FeatureEngineering1.ipynb b/FeatureEngineering/DB_FeatureEngineering1.ipynb old mode 100644 new mode 100755 index 5d2b8ea..4d428a4 --- a/FeatureEngineering/DB_FeatureEngineering1.ipynb +++ b/FeatureEngineering/DB_FeatureEngineering1.ipynb @@ -2,10 +2,21 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, - "id": "756b4af0", + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'tensorflow'", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_85224/4219686290.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mmath\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msqrt\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 13\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 14\u001b[1;33m \u001b[1;32mimport\u001b[0m \u001b[0mtensorflow\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mtf\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 15\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[1;31m# Keras specific\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'tensorflow'" + ], + "output_type": "error" + } + ], "source": [ "import pandas as pd\n", "import numpy as np\n", @@ -31,7 +42,6 @@ { "cell_type": "code", "execution_count": 2, - "id": "3dc2fae7", "metadata": { "scrolled": true }, @@ -42,22 +52,25 @@ }, { "cell_type": "code", - "execution_count": 3, - "id": "424466af", + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "#load data from data files and place into panda dataframes\n", - "custOrders = pd.read_csv('data/customer_orders.csv', low_memory=False)\n", - "temp2 = pd.read_csv('data/item_ingredients.csv', low_memory=False)\n", - "\n", + "try:\n", + " custOrders = pd.read_csv('data/customer_orders.csv', low_memory=False)\n", + " temp2 = pd.read_csv('data/item_ingredients.csv', low_memory=False)\n", + "except FileNotFoundError:\n", + " c_order_url = \"https://raw.githubusercontent.com/GottaGitGoing/cs180_2/main/FeatureEngineering/data/customer_orders.csv\"\n", + " ingred_url = \"https://raw.githubusercontent.com/GottaGitGoing/cs180_2/main/FeatureEngineering/data/item_ingredients.csv\"\n", + " custOrders = pd.read_csv(c_order_url, low_memory=False)\n", + " temp2 = pd.read_csv(ingred_url, low_memory=False)\n", "#temp2.head(10)\n" ] }, { "cell_type": "code", "execution_count": 4, - "id": "930462cc", "metadata": {}, "outputs": [ { @@ -82,7 +95,6 @@ { "cell_type": "code", "execution_count": 5, - "id": "a397d1f3", "metadata": {}, "outputs": [ { @@ -123,7 +135,6 @@ { "cell_type": "code", "execution_count": 6, - "id": "bcb78d34", "metadata": { "scrolled": true }, @@ -148,7 +159,6 @@ { "cell_type": "code", "execution_count": 7, - "id": "51657c7f", "metadata": { "scrolled": true }, @@ -336,7 +346,6 @@ { "cell_type": "code", "execution_count": 8, - "id": "41d402ed", "metadata": {}, "outputs": [ { @@ -520,7 +529,6 @@ { "cell_type": "code", "execution_count": 9, - "id": "1e4230cc", "metadata": {}, "outputs": [], "source": [ @@ -545,7 +553,6 @@ { "cell_type": "code", "execution_count": 10, - "id": "c1f14dd0", "metadata": {}, "outputs": [], "source": [ @@ -571,7 +578,6 @@ { "cell_type": "code", "execution_count": 11, - "id": "ee755b25", "metadata": { "scrolled": true }, @@ -988,7 +994,6 @@ { "cell_type": "code", "execution_count": 12, - "id": "471ddcc9", "metadata": {}, "outputs": [ { @@ -1010,7 +1015,6 @@ { "cell_type": "code", "execution_count": 13, - "id": "69e86727", "metadata": {}, "outputs": [], "source": [ @@ -1037,7 +1041,6 @@ { "cell_type": "code", "execution_count": 14, - "id": "c1e36854", "metadata": { "scrolled": true }, @@ -1331,7 +1334,6 @@ { "cell_type": "code", "execution_count": 15, - "id": "556b6059", "metadata": { "scrolled": true }, @@ -1506,7 +1508,6 @@ { "cell_type": "code", "execution_count": 16, - "id": "98c25c78", "metadata": {}, "outputs": [ { @@ -1555,7 +1556,6 @@ { "cell_type": "code", "execution_count": 17, - "id": "736b10a3", "metadata": {}, "outputs": [ { @@ -1914,7 +1914,6 @@ { "cell_type": "code", "execution_count": 18, - "id": "85955bdd", "metadata": {}, "outputs": [], "source": [ @@ -1939,7 +1938,6 @@ { "cell_type": "code", "execution_count": 19, - "id": "a0f9ecd7", "metadata": {}, "outputs": [], "source": [ @@ -1953,7 +1951,6 @@ { "cell_type": "code", "execution_count": 20, - "id": "cf656e7d", "metadata": {}, "outputs": [], "source": [ @@ -1968,7 +1965,6 @@ { "cell_type": "code", "execution_count": 21, - "id": "eb8a4c34", "metadata": {}, "outputs": [ { @@ -1993,7 +1989,6 @@ { "cell_type": "code", "execution_count": 22, - "id": "dfb6d45e", "metadata": {}, "outputs": [], "source": [ @@ -2004,7 +1999,6 @@ { "cell_type": "code", "execution_count": 23, - "id": "4ac99c03", "metadata": {}, "outputs": [ { @@ -2025,7 +2019,6 @@ { "cell_type": "code", "execution_count": 24, - "id": "4186cf86", "metadata": {}, "outputs": [], "source": [ @@ -2041,7 +2034,6 @@ { "cell_type": "code", "execution_count": 25, - "id": "26e33f9a", "metadata": { "scrolled": true }, @@ -2280,7 +2272,6 @@ { "cell_type": "code", "execution_count": 26, - "id": "f4247c08", "metadata": {}, "outputs": [ { @@ -2302,7 +2293,6 @@ { "cell_type": "code", "execution_count": 27, - "id": "69297008", "metadata": {}, "outputs": [ { @@ -2332,7 +2322,6 @@ { "cell_type": "code", "execution_count": null, - "id": "3aeeb1f8", "metadata": {}, "outputs": [], "source": [] diff --git a/SQL/CSVs/itemrestrictions.csv b/SQL/CSVs/itemrestrictions.csv new file mode 100755 index 0000000..f6d4c91 --- /dev/null +++ b/SQL/CSVs/itemrestrictions.csv @@ -0,0 +1,22 @@ +item_id,dairy,nuts,vegan,vegetarian,kosher,halal +640404923,0,0,0,0,0,0 +640404963,0,0,0,0,0,0 +640405025,0,0,0,0,0,0 +640405058,0,1,1,1,0,0 +640405085,0,0,0,0,0,0 +640405112,0,0,0,0,0,0 +640405172,0,0,0,0,0,0 +640405355,0,0,1,1,1,1 +640405371,0,0,1,1,1,1 +640405380,0,0,1,1,1,1 +640405389,1,1,0,0,1,1 +640405395,1,1,0,0,1,1 +640405399,1,1,0,0,1,1 +640405296,0,0,1,1,1,1 +640405307,0,0,1,1,1,1 +640405315,0,0,1,1,1,1 +640405323,0,0,1,1,1,1 +640405331,0,0,1,1,1,1 +640405339,0,0,1,1,1,1 +640405347,0,0,1,1,1,1 +640405348,0,0,1,1,1,1 \ No newline at end of file diff --git a/SQL/csv_generator.py b/SQL/csv_generator.py old mode 100644 new mode 100755 index 6809a3f..253677d --- a/SQL/csv_generator.py +++ b/SQL/csv_generator.py @@ -1,6 +1,6 @@ from collections import defaultdict import random - +import csv NUM_CUSTOMERS = 200 NUM_ORDERS = 2000 @@ -8,6 +8,8 @@ def ingredient(): + '''Populates ingredient.csv with ingredient_id and ingredient_name + given the ingredient_types declared here. Returns csv content as dict().''' columns = ['ingredient_id', 'ingredient_name'] ingredient_types = ['ketchup', 'mustard', @@ -43,6 +45,8 @@ def ingredient(): def itemingredient(ingredients_dict): + '''Populates itemingredient.csv with item_id and ingredient_id + given the ingredients for each item.''' columns = ['item_id', 'ingredient_id'] items = { 640404923: "Ketchup, Mustard, Mayonnaise, Lettuce, Pickles, Onions, Tomatoes", @@ -79,6 +83,9 @@ def itemingredient(ingredients_dict): def menu(): + '''Currently assigns menu_id to each item_id with all the + same restaurant brand and store_id. (i.e. All items belong + to the same store.) Populates menu.csv.''' columns = ['menu_id', 'item_id', 'brand', 'store_id'] item_ids = [ 640404923, @@ -112,6 +119,10 @@ def menu(): def customer(): + '''Generates {NUM_CUSTOMERS} customers with random attributes except + everyone has opt_in = true because we have this information only for + opt_in folks as of now. Populates customer.csv.''' + columns = ['customer_id', 'opt_in', 'birthday', 'gender'] genders = [ 'male', @@ -128,6 +139,8 @@ def customer(): def order(): + '''Generates {NUM_ORDERS} orders with order_id, a random customer_id, + a random timestamp between 2015 and 2020, and weather chosen from a list.''' columns = ['order_id', 'customer_id', 'order_timestamp', 'weather'] weather = [ 'sunny', @@ -147,6 +160,8 @@ def order(): def orderitem(): + '''Associates random item_id for each order_id.''' + columns = ['order_id', 'item_id'] item_ids = [ 640404923, @@ -178,14 +193,102 @@ def orderitem(): file.write(','.join(columns) + '\n') for id in range(1, NUM_ORDERS + 1): - item_id = random.choice(item_ids) + # here check if item id fits the preference + # id is order_id + c_id = get_customer_id_from_order(id) # need c_id because we need to check the customers preference + # now we have customer_id associated with the orderitem. check the + # customers restrictions and run random.choice until a valid item is + # picked. (or create a separate list that + cust_diet_restriction = get_customer_diet_restr(c_id) + while True: + item_id = random.choice(item_ids) + restriction_list = get_item_restrictions(item_id) + # now check restriction list returns and see if it contains + # any of the customer diet restrictions + # NOTE: the list returned will be format + # item_id,dairy,nuts,vegan,vegetarian,kosher,halal + + # GOAL: using restriction_list and cust_diet_restriction + # see if the random choice is appropriate. if not appropriate + # randomly choose again. + rest_map = {"dairy":1,"nuts":2,"vegan":3, + "vegetarian":4,"kosher":5,"halal":6} + for pref_id,pref in cust_diet_restriction.items(): + if restriction_list[pref] == 1: + # something something + + + rest_comp_list = ['0', '0', '0', '0', '0', '0'] + + file.write(f'{id},{item_id}\n') orders[item_id].append(id) return orders +def get_item_restrictions(item_id:int): + '''Given an item_id, it will return a list of restrictions applicable to + the specfic item_id.''' + with open("CSVs/itemrestrictions.csv", "r") as REST_FILE: + data = csv.reader(REST_FILE) + # calling next so the data iterator skips the header. + # Better than try except imo. + next(data) + for itm in data: + if int(itm[0]) == item_id: + return itm + return -1 # to indicate not item_id found + + +def get_customer_diet_restr(cust_id: int): + '''Returns a dictionary of dietary id:preference of a given customer. If the + customer does not exist, or no preference found, + then empty dictionary is returned''' + + # loop thru custdiepref.csv and returns + # the dietary pref id and actual pref txt + preference_id_set = set() # list since cust could be halal and vegan + with open("CSVs/customerdietarypreference.csv", "r") as FILE: + data = csv.reader(FILE) + for i in data: + try: + if int(i[0]) == cust_id: + print(i[1]) + preference_id_set.add(i[1]) + # NOTE MIGHT NEED to typecast to int + except ValueError: # reasoning is checking str vs int might fail + pass + + # now you have the set of preference for a customer. make a dict of + # preference_id and preference + pref_id_name = dict() + if len(preference_id_set) != 0: + with open("CSVs/dietarypreference.csv", "r") as FILE: + data = csv.reader(FILE) + pref_id_name = {id:pref_name for id,pref_name,weight in data + if id in preference_id_set} + return pref_id_name # returns dict of pref_id's and their name of pref + + +def get_customer_id_from_order(id: int): + ''' returns c_id by searching through order.csv. ''' + with open("CSVs/order.csv", "r") as FILE: + data = csv.reader(FILE) + # order id 7. expeects 171 back + for i in data: + try: + if int(i[0]) == id: + return i[1] + except ValueError: + pass # this is because i havent skipped the csv header so + # this will just "ignore" the title since strings cant be ints + def customization(): + '''Menu items with customizable features (ingredients that + can be taken out) propagate customization.csv which each + menu item - customization pair. (E.g. burger_type1 with no ketchup + could be a row and burger_type1 with no mustard could be another.''' columns = ['customization_id', 'item_id', 'customization'] customizations = [ 'no ketchup', @@ -236,6 +339,8 @@ def customization(): def orderitemcustomization(orders, customization_dict): + '''Pairs {NUM_ORDER_ITEM_CUSTOMIZATIONS} random orders with customizations + where the item_id matches.''' columns = ['order_id', 'item_id', 'customization_id'] order_item_customizations = set() @@ -255,7 +360,10 @@ def orderitemcustomization(orders, customization_dict): file.write(f'{row[0]},{row[1]},{row[2]}\n') + def dietarypreference(): + '''For each preference, a weight of 1 - 5 is assigned as a pair (not random, + so total rows = len(preferences)*5.''' columns = ['preference_id', 'preference', 'preference_weight'] preferences = [ 'dairy', @@ -282,6 +390,8 @@ def dietarypreference(): def customerdietarypreference(preference_weight_pairs): + '''Every few customers will have a preference attached to them.''' + columns = ['customer_id', 'preference_id'] customer_dietary_preference_pairs = set() @@ -296,13 +406,20 @@ def customerdietarypreference(preference_weight_pairs): if __name__ == '__main__': - ingredients_dict = ingredient() - itemingredient(ingredients_dict) - menu() - customer() - order() - orders = orderitem() - customization_dict = customization() - orderitemcustomization(orders, customization_dict) - preference_weight_pairs = dietarypreference() - customerdietarypreference(preference_weight_pairs) + # ingredients_dict = ingredient() + # itemingredient(ingredients_dict) + # menu() + # customer() + # order() + # preference_weight_pairs = dietarypreference() + # customerdietarypreference(preference_weight_pairs) + # orders = orderitem() + # customization_dict = customization() + # orderitemcustomization(orders, customization_dict) + + + ## TESTER!! + print(get_customer_diet_restr(23)) + # get_customer_id_from_order(7) + print(get_item_restrictions(640404923)) +