from flask import Flask
from flask_sqlalchemy import SQLAlchemy


"""
These object and definitions are used throughout the Jupyter Notebook.
"""


# Setup of key Flask object (app)
app = Flask(__name__)
# Setup SQLAlchemy object and properties for the database (db)
database = 'sqlite:///sqlite.db' # path and filename of database
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = database
app.config['SECRET_KEY'] = 'SECRET_KEY'
db = SQLAlchemy()




# This belongs in place where it runs once per project
db.init_app(app)
import datetime
from datetime import datetime
import json


from sqlalchemy.exc import IntegrityError
from werkzeug.security import generate_password_hash, check_password_hash


class Nutrition(db.Model):
    __tablename__ = 'nutritions'
   
   
   
    id = db.Column(db.Integer, primary_key=True)
    _username = db.Column(db.String(255), unique=False, nullable=False)
    _foodname = db.Column(db.String(255), unique=False, nullable=False)
    _calories = db.Column(db.String(255), unique=False, nullable=False)
    _fat = db.Column(db.String(255), unique=False, nullable=False)
    _carbs = db.Column(db.String(255), unique=False, nullable=False)
   
   
    def __init__(self, username, foodname, calories,fat, carbs):
       
        self._username = username  
        self._foodname = foodname    # variables with self prefix become part of the object,
        self._calories = calories
        self._fat = fat
        self._carbs = carbs
   
    @property
    def username(self):
        return self._username
   
   
    # a setter function, allows name to be updated after initial object creation
    @username.setter
    def username(self, username):
        self._name = username    
       
    @property
    def foodname(self):
        return self._foodname
   
   
    # a setter function, allows name to be updated after initial object creation
    @foodname.setter
    def foodname(self, foodname):
        self._foodname = foodname
       
       
       
    # a getter method, extracts link from object
    @property
    def calories(self):
        return self._calories
   
   
    # a setter function, allows link to be updated after initial object creation
    @calories.setter
    def calories(self, calories):
        self._calories = calories
       
       
       
    # a getter method, extracts link from object
    @property
    def fat(self):
        return self._fat
   
   
   
    # a setter function, allows link to be updated after initial object creation
    @fat.setter
    def fat(self, fat):
        self._fat = fat
       
       


    # a getter method, extracts link from object
    @property
    def carbs(self):
        return self._carbs
   
   
   
    # a setter function, allows link to be updated after initial object creation
    @carbs.setter
    def carbs(self, carbs):
        self._carbs = carbs
       
    def __str__(self):
        return json.dumps(self.read())
   
    
       
    
    

    
def create(self):
        try:
            # creates a person object from User(db.Model) class, passes initializers
            db.session.add(self)  # add prepares to persist person object to Users table
            db.session.commit()  # SqlAlchemy "unit of work pattern" requires a manual commit
            return self
        except IntegrityError:
            db.session.remove()
            return None
    # returns dictionary
def read(self):
        return {
            "id": self.id,
            "username": self.username,
            "foodname" : self.foodname,
            "calories" : self.calories,
            "fat" : self.fat,
            "carbs" : self.carbs,
        }
import sqlite3

# CRUD update: updates user name, password, phone
    # returns self
def update(self, username="", foodname="", calories="", fat="", carbs=""):
        """only updates values with length"""
        if len(username) > 0:
            self.username = username
           
        if len(foodname) > 0:
            self.foodname = foodname
           
        if len(calories) > 0:
            self.calories = calories
           
        if len(fat) > 0:
            self.fat = fat
           
        if len(carbs) > 0:
            self.carbs = carbs
           
        db.session.commit()
        return self
    # None
def delete(self):
        db.session.delete(self)
        db.session.commit()
        return None
"""Database Creation and Testing """




# Builds working data for testing
def initNutrition():
    with app.app_context():
        """Create database and tables"""
        db.create_all()
        """Tester data for table"""
        r1 = Nutrition(username = 'Ananya', foodname='Apple', calories='94 cal',fat='0.31g', carbs='20.77 g')
        r2 = Nutrition(username = 'Haseeb', foodname='Flour', calories='455.00 kcal', fat=' 1.23 g', carbs='92.01 g')
        r3 = Nutrition(username = 'Ethan',foodname='Orange', calories=' 61.57 kcal', fat='0.16 g', carbs='12.25 g')
        r4 = Nutrition(username = 'Alexa',foodname='Milk',calories='148.84 kcal', fat='7.93 g',carbs=' 11.71 g')
        r5 = Nutrition(username = 'Ava',foodname='Egg', calories='61.49 kcal', fat='4.09 g', carbs=' 0.31 g')
       
   
        nutritions = [r1, r2, r3, r4, r5]


        """Builds sample user/note(s) data"""
        for nutrition in nutritions:
            try:
                nutrition.create()
            except IntegrityError:
                '''fails with bad or duplicate data'''
                db.session.remove()
                print(f"Records exist, duplicate email, or error: {nutrition.model}")


initNutrition()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb Cell 7 in <cell line: 32>()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=27'>28</a>                 db.session.remove()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=28'>29</a>                 print(f"Records exist, duplicate email, or error: {nutrition.model}")
---> <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=31'>32</a> initNutrition()

/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb Cell 7 in initNutrition()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=22'>23</a> for nutrition in nutritions:
     <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=23'>24</a>     try:
---> <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=24'>25</a>         nutrition.create()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=25'>26</a>     except IntegrityError:
     <a href='vscode-notebook-cell://wsl%2Bubuntu/home/ananyag2617/vscode/ananyagaurav2617/_notebooks/2023-03-19-database.ipynb#W2sdnNjb2RlLXJlbW90ZQ%3D%3D?line=26'>27</a>         '''fails with bad or duplicate data'''

AttributeError: 'Nutrition' object has no attribute 'create'
def create():
    # optimize user time to see if uid exists
    username = input("Enter your name:")
    try:
        print("Found\n", username.read())
        return
    except:
        pass # keep going
    
    # request value that ensure creating valid object
    username = input("Enter your name:")
    foodname = input("Enter the name of the food:")
    calories = input("Enter the number of calories:")
    fat = input("Enter the number of fat:")
    carbs = input("Enter information about carbs:")
   
    # Initialize User object before date
    user = Nutrition(
               username=username,
                foodname=foodname, 
                calories=calories, 
                fat=fat,
                carbs=carbs,
                )
    
    
    # write object to database
    with app.app_context():
        try:
            object = user.create()
            print("Created\n", object.read())
        except:  # error raised if object not created
            print("Unknown error uid {username}")
        
create()
Unknown error uid {username}