"""
These imports define the key objects
"""

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)
class Car(db.Model):
    __tablename__ = 'cars'  # table name is plural, class name is singular

    # Define the User schema with "vars" from object
    id = db.Column(db.Integer, unique=True, primary_key=True)
    _brand = db.Column(db.String(255), unique=False, nullable=False)
    _color = db.Column(db.Integer, unique=False, nullable=False)
    _powersource = db.Column(db.String(255), unique=False, nullable=False)
    _type = db.Column(db.String(255), unique=False, nullable=False)
   

    # constructor of a User object, initializes the instance variables within object (self)
    def __init__(self, brand, color, type, powersource):
        self._brand = brand
        self._color = color
        self._powersource = powersource
        self._type = type 
        
    # gets the brand the car
    @property
    def brand(self):
        return self._brand
    
    # a setter function, allows brand to be updated after initial object creation
    @brand.setter
    def brand(self, brand):
        self._brand = brand

     # gets the color of the car
    @property
    def color(self):
        return self._color
    
    # a setter function, allows color to be updated after initial object creation
    @color.setter
    def color(self, color):
        self._color = color

    # gets the type of the manufacturer or the car
    @property
    def type(self):
        return self._type
    
    # a setter function, allows type to be updated after initial object creation
    @type.setter
    def type(self, type):
        self._type = type
    
    # a powersource getter
    @property
    def powersource(self):
        return self._powersource

    # a setter function to set the car's powersource
    @powersource.setter
    def powersource(self, powersource):
        self._powersource = powersource
        

    # CRUD read converts self to dictionary
    # returns dictionary
    def read(self):
        return {
            "id": self.id,
            "brand" : self.brand,
            "color" : self.color,
            "powersource" : self.powersource,
            "type" : self.type,
        }
     
    def update(self, brand="", color="", powersource="", type=""):
        """only updates values with length"""
        if len(brand) > 0:
            self.brand = brand
        if len(color) > 0:
            self.color = color
        if len(powersource) > 0:
            self.powersource = powersource
        if len(type) > 0:
            self.type = type
        db.session.add(self) # performs update when id exists\n",
        db.session.commit()
        return self

    def delete(self):
        db.session.delete(self)
        db.session.commit()
        return None
def initCars():
    with app.app_context():
        """Create database and tables"""
        db.create_all()

        """Tester data for table"""
        c1 = Car(brand='Acura', color='gray', powersource='ice', type='suv')
        c2 = Car(brand='Hyundai', color='red', powersource='ice', type='sedan') 
        c3 = Car(brand='Mazda', color='white', powersource='ice', type='sedan')
        c4 = Car(brand='Honda', color='gray', powersource='ice', type='suv')
        c5 = Car(brand='Dodge', color='black', powersource='ice', type='suv')
        c6 = Car(brand='Toyota', color='white', powersource='ice', type='truck') 
        c7 = Car(brand='Hyundai', color='blue', powersource='ice', type='sedan')
        c8 = Car(brand='Chevrolet', color='gray', powersource='ice', type='truck')
        c9 = Car(brand='Jeep', color='gray', powersource='ice', type='suv')
        c10 = Car(brand='Nissan', color='silver', powersource='ice', type='sedan') 
        c11 = Car(brand='Lexus', color='black', powersource='ice', type='sedan')
        c12 = Car(brand='Kia', color='red', powersource='ice', type='suv')
        c13 = Car(brand='Mazda', color='red', powersource='ice', type='truck')
        c14 = Car(brand='Ford', color='white', powersource='ice', type='sedan') 
        c15 = Car(brand='Kia', color='red', powersource='ice', type='truck')
        c16 = Car(brand='Ford', color='gray', powersource='ice', type='suv')
        c17 = Car(brand='Jeep', color='red', powersource='ice', type='truck')
        c18 = Car(brand='Toyota', color='red', powersource='electric', type='suv') 
        c19 = Car(brand='Kia', color='silver', powersource='ice', type='truck')
        c20 = Car(brand='Honda', color='white', powersource='ice', type='suv')
        c21 = Car(brand='Hyundai', color='white', powersource='ice', type='sedan')
        c22 = Car(brand='Chevrolet', color='white', powersource='ice', type='suv') 
        c23 = Car(brand='Jeep', color='white', powersource='ice', type='suv')
        c24 = Car(brand='BMW', color='gray', powersource='ice', type='sedan')
        c25 = Car(brand='Ferrari', color='yellow', powersource='ice', type='sports')
        c26 = Car(brand='Tesla', color='red', powersource='electric', type='suv') 
        c27 = Car(brand='Tesla', color='blue', powersource='electric', type='suv')
        c28 = Car(brand='Ford', color='white', powersource='electric', type='truck')
        c29 = Car(brand='Ford', color='blue', powersource='electric', type='truck')
        c30 = Car(brand='Audi', color='black', powersource='electric', type='suv') 
        c31 = Car(brand='Ferrari', color='red', powersource='electric', type='sports')
        c32 = Car(brand='Mercedes', color='silver', powersource='electric', type='sedan')
        c33 = Car(brand='Mazda', color='silver', powersource='electric', type='suv')
        c34 = Car(brand='Nissan', color='blue', powersource='electric', type='suv') 
        c35 = Car(brand='Subaru', color='red', powersource='electric', type='suv')

        cars = [c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31, c32, c33, c34, c35]

        """Builds sample car/note(s) data"""
        for user in cars:
            try:
                '''add car to table'''
                object = Car.create()
                print(f"Created new car {object.Car}")
            except:  # error raised if object nit created
                '''fails with bad or duplicate data'''
                print(f"Records exist car {user.Car}, or error.")
                
initCars()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/mnt/c/Users/Sarah Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb Cell 4 in initCars()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=47'>48</a> '''add car to table'''
---> <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=48'>49</a> object = Car.create()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=49'>50</a> print(f"Created new car {object.Car}")

AttributeError: type object 'Car' has no attribute 'create'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
/mnt/c/Users/Sarah Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb Cell 4 in <cell line: 55>()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=51'>52</a>                 '''fails with bad or duplicate data'''
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=52'>53</a>                 print(f"Records exist car {user.Car}, or error.")
---> <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=54'>55</a> initCars()

/mnt/c/Users/Sarah Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb Cell 4 in initCars()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=50'>51</a> except:  # error raised if object nit created
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=51'>52</a>     '''fails with bad or duplicate data'''
---> <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W3sdnNjb2RlLXJlbW90ZQ%3D%3D?line=52'>53</a>     print(f"Records exist car {user.Car}, or error.")

AttributeError: 'Car' object has no attribute 'Car'
def createCar():
    uid = input("Enter your car id:")
    try:
        print("Found\n", car.read())
        return
    except:
        pass # keep going

    # request value that ensure creating valid object
    brand = input("What brand is the car?")
    color = input("What color is the car?")
    powersource = input("What is the car's powersource?")
    type = input("What type of car is it?") 
    
    # Initialize User object before date
    car = Car(brand=brand,
                color=color, 
                powersource=powersource,
                type=type
                )
       
    # write object to database
    with app.app_context():
        try:
            object = car.create()
            print("Created\n", object.read())
        except:  # error raised if object not created
            print("Unknown error powersource {uid}")
        
createCar()
Unknown error powersource {uid}
def readCar():
    with app.app_context():
        table = Car.query.all()
    json_ready = [car.read() for car in table] # "List Comprehensions", for each car add car.read() to list
    return json_ready

readCar()
[{'id': 1,
  'brand': 'Acura',
  'color': 'gray',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 2,
  'brand': 'Hyundai',
  'color': 'red',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 3,
  'brand': 'Mazda',
  'color': 'white',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 4,
  'brand': 'Honda',
  'color': 'gray',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 5,
  'brand': 'Dodge',
  'color': 'black',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 6,
  'brand': 'Toyota',
  'color': 'white',
  'powersource': 'ice',
  'type': 'truck'},
 {'id': 7,
  'brand': 'Hyundai',
  'color': 'blue',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 8,
  'brand': 'Chevrolet',
  'color': 'gray',
  'powersource': 'ice',
  'type': 'truck'},
 {'id': 9,
  'brand': 'Jeep',
  'color': 'gray',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 10,
  'brand': 'Nissan',
  'color': 'silver',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 11,
  'brand': 'Lexus',
  'color': 'black',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 12,
  'brand': 'Kia',
  'color': 'red',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 13,
  'brand': 'Mazda',
  'color': 'red',
  'powersource': 'ice',
  'type': 'truck'},
 {'id': 14,
  'brand': 'Ford',
  'color': 'white',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 15,
  'brand': 'Kia',
  'color': 'red',
  'powersource': 'ice',
  'type': 'truck'},
 {'id': 16,
  'brand': 'Ford',
  'color': 'gray',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 17,
  'brand': 'Jeep',
  'color': 'red',
  'powersource': 'ice',
  'type': 'truck'},
 {'id': 18,
  'brand': 'Toyota',
  'color': 'red',
  'powersource': 'electric',
  'type': 'suv'},
 {'id': 19,
  'brand': 'Kia',
  'color': 'silver',
  'powersource': 'ice',
  'type': 'truck'},
 {'id': 20,
  'brand': 'Honda',
  'color': 'white',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 21,
  'brand': 'Hyundai',
  'color': 'white',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 22,
  'brand': 'Chevrolet',
  'color': 'white',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 23,
  'brand': 'Jeep',
  'color': 'white',
  'powersource': 'ice',
  'type': 'suv'},
 {'id': 24,
  'brand': 'BMW',
  'color': 'gray',
  'powersource': 'ice',
  'type': 'sedan'},
 {'id': 25,
  'brand': 'Ferrari',
  'color': 'yellow',
  'powersource': 'ice',
  'type': 'sports'},
 {'id': 26,
  'brand': 'Tesla',
  'color': 'red',
  'powersource': 'electric',
  'type': 'suv'},
 {'id': 27,
  'brand': 'Tesla',
  'color': 'blue',
  'powersource': 'electric',
  'type': 'suv'},
 {'id': 28,
  'brand': 'Ford',
  'color': 'white',
  'powersource': 'electric',
  'type': 'truck'},
 {'id': 29,
  'brand': 'Ford',
  'color': 'blue',
  'powersource': 'electric',
  'type': 'truck'},
 {'id': 30,
  'brand': 'Audi',
  'color': 'black',
  'powersource': 'electric',
  'type': 'suv'},
 {'id': 31,
  'brand': 'Ferrari',
  'color': 'red',
  'powersource': 'electric',
  'type': 'sports'},
 {'id': 32,
  'brand': 'Mercedes',
  'color': 'silver',
  'powersource': 'electric',
  'type': 'sedan'},
 {'id': 33,
  'brand': 'Mazda',
  'color': 'silver',
  'powersource': 'electric',
  'type': 'suv'},
 {'id': 34,
  'brand': 'Nissan',
  'color': 'blue',
  'powersource': 'electric',
  'type': 'suv'},
 {'id': 35,
  'brand': 'Subaru',
  'color': 'red',
  'powersource': 'electric',
  'type': 'suv'}]
def updateCar(uid, new_brand, new_color, new_powersource, new_type):
    with app.app_context():
        car = db.session.query(Car).filter_by(_uid=uid).first()
        try:
            print("Found\n", car.read())

            car.update(new_brand, new_color, new_powersource, new_type)
        
            return
        except:
            pass # keep going

new_brand = input("Enter new brand:")
new_color = input("Enter new color:")
new_powersource = input("Enter new powersource:")
new_type = input("Enter new type:")

updateCar(new_brand, new_color, new_powersource, new_type)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/mnt/c/Users/Sarah Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb Cell 7 in <cell line: 18>()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=14'>15</a> new_powersource = input("Enter new powersource:")
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=15'>16</a> new_type = input("Enter new type:")
---> <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#W6sdnNjb2RlLXJlbW90ZQ%3D%3D?line=17'>18</a> updateCar(new_brand, new_color, new_powersource, new_type)

TypeError: updateCar() missing 1 required positional argument: 'new_type'
def deleteCar(uid):
    with app.app_context():
        car = db.session.query(Car).filter_by(_uid=uid).first()
        try:
            print("Found\n", car.read())

            car.delete()
        
            return
        except:
            pass # keep going

uid = input("Enter your car uid:")
deleteCar(uid)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~/anaconda3/lib/python3.9/site-packages/sqlalchemy/sql/base.py:2120, in _entity_namespace_key(entity, key, default)
   2119     else:
-> 2120         return getattr(ns, key)  # type: ignore
   2121 except AttributeError as err:

AttributeError: type object 'Car' has no attribute '_uid'

The above exception was the direct cause of the following exception:

InvalidRequestError                       Traceback (most recent call last)
/mnt/c/Users/Sarah Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb Cell 8 in <cell line: 14>()
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=10'>11</a>             pass # keep going
     <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=12'>13</a> uid = input("Enter your car uid:")
---> <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=13'>14</a> deleteCar(uid)

/mnt/c/Users/Sarah Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb Cell 8 in deleteCar(uid)
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=0'>1</a> def deleteCar(uid):
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=1'>2</a>     with app.app_context():
----> <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=2'>3</a>         car = db.session.query(Car).filter_by(_uid=uid).first()
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=3'>4</a>         try:
      <a href='vscode-notebook-cell://wsl%2Bubuntu/mnt/c/Users/Sarah%20Liu/vscode/Sarah-Liu/_notebooks/2023-03-13-hacksfor2-4a.ipynb#X10sdnNjb2RlLXJlbW90ZQ%3D%3D?line=4'>5</a>             print("Found\n", car.read())

File ~/anaconda3/lib/python3.9/site-packages/sqlalchemy/orm/query.py:1998, in Query.filter_by(self, **kwargs)
   1971 r"""Apply the given filtering criterion to a copy
   1972 of this :class:`_query.Query`, using keyword expressions.
   1973 
   (...)
   1994 
   1995 """
   1996 from_entity = self._filter_by_zero()
-> 1998 clauses = [
   1999     _entity_namespace_key(from_entity, key) == value
   2000     for key, value in kwargs.items()
   2001 ]
   2002 return self.filter(*clauses)

File ~/anaconda3/lib/python3.9/site-packages/sqlalchemy/orm/query.py:1999, in <listcomp>(.0)
   1971 r"""Apply the given filtering criterion to a copy
   1972 of this :class:`_query.Query`, using keyword expressions.
   1973 
   (...)
   1994 
   1995 """
   1996 from_entity = self._filter_by_zero()
   1998 clauses = [
-> 1999     _entity_namespace_key(from_entity, key) == value
   2000     for key, value in kwargs.items()
   2001 ]
   2002 return self.filter(*clauses)

File ~/anaconda3/lib/python3.9/site-packages/sqlalchemy/sql/base.py:2122, in _entity_namespace_key(entity, key, default)
   2120         return getattr(ns, key)  # type: ignore
   2121 except AttributeError as err:
-> 2122     raise exc.InvalidRequestError(
   2123         'Entity namespace for "%s" has no property "%s"' % (entity, key)
   2124     ) from err

InvalidRequestError: Entity namespace for "cars" has no property "_uid"