Create

"""
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)
import datetime

import json

from datetime import datetime

from sqlalchemy.exc import IntegrityError



class Game(db.Model):
    __tablename__ = 'games'

    # added this after getting an error that the table had already been defined
    __table_args__ = {'extend_existing': True}


    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), unique=True, nullable=False)
    price = db.Column(db.Float, nullable=False)
    release_date = db.Column(db.Date, nullable=False)
    developer = db.Column(db.String(255), nullable=False)
    publisher = db.Column(db.String(255), nullable=False)

    def __init__(self, name, price, release_date, developer, publisher):
        self.name = name
        self.price = price
        self.release_date = release_date
        self.developer = developer
        self.publisher = publisher

    @property
    def game_info(self):
        return self.read()

    def create(self):
        try:
            db.session.add(self)
            db.session.commit()
            return self
        except IntegrityError:
            db.session.remove()
            return None

    def read(self):
        return {
            "id": self.id,
            "name": self.name,
            "price": self.price,
            "release_date": self.release_date,
            "developer": self.developer,
            "publisher": self.publisher,
        }

    def update(self, name="", price="", release_date="", developer="", publisher=""):
        if len(name) > 0:
            self.name = name
        if len(price) > 0:
            self.price = price
        if len(release_date) > 0:
            self.release_date = release_date
        if len(developer) > 0:
            self.developer = developer
        if len(publisher) > 0:
            self.publisher = publisher
        db.session.commit()
        return self

    def delete(self):
        db.session.delete(self)
        db.session.commit()
        return None
"""Database Creation and Testing """


# Builds working data for testing
def initGames():
    with app.app_context():
        """Create database and tables"""
        db.create_all()
        """Tester data for table"""
        g1 = Game(name='Mario Party 9', price=169.00, release_date=datetime(2012, 2, 3), developer='NDcube', publisher='Nintendo')
        g2 = Game(name='Legend of Zelda: Tears of the Kingdom', price=69.99, release_date=datetime(2023, 5, 12), developer='Nintendo Entertaining Planning and Development', publisher='Nintendo')
 
        # locals include age, name, date of birth, user id, etc.
        # debugging allows you to go in to see if there is any problems with your code (ex. missing an attribute like user id)
        # once you have your users, your sqlite.db file is created 

        games = [g1, g2]

        """Builds sample user/note(s) data"""
        for game in games:
            try:
                '''add user to table'''
                object = game.create()
                print(f"Created new uid {object.name}")
            except:  # error raised if object nit created
                '''fails with bad or duplicate data'''
                print(f"Records exist uid {game.name}, or error.")
                
initGames()
Records exist uid Mario Party 9, or error.
Records exist uid Legend of Zelda: Tears of the Kingdom, or error.
def find_by_name(Name):
    with app.app_context():
        game = Game.query.filter_by(Name=Name).first()
    return game

        
#check_credentials("indi", "123qwerty")

Create

def create():
    # optimize user time to see if uid exists
    name = input("Enter the name of your game:")
    game = find_by_name(name)
    try:
        print("Found\n", game.read())
        return
    except:
        pass # keep going
    
    # request value that ensure creating valid object
    price = float(input("Enter the price of your game"))
    developer = input("Enter the developer of your game")
    publisher = input("Enter the publisher of your game")
    
    
    # Initialize User object before date
    game = Game(name=name, 
                price=price, 
                developer=developer,
                publisher=publisher,
                release_date=datetime.today().date()
                )
    
    # create user.dob, fail with today as dob
    release_date = input("Enter the date your game was (or is to be) released (YYYY-MM-DD)")
    try:
        game.release_date = datetime.strptime(release_date, '%Y-%m-%d').date()
    except ValueError:
        game.release_date = datetime.today()
        print(f"Invalid date {release_date} require YYYY-mm-dd, date defaulted to {game.release_date}")
           
    # write object to database
    with app.app_context():
        try:
            object = game.create()
            print("Created\n", object.read())
        except:  # error raised if object not created
            print("Unknown error name {name}")
        
create()
Created
 {'id': 4, 'name': 'Overwatch', 'price': 60.0, 'release_date': datetime.date(2016, 11, 20), 'developer': 'Blizzard', 'publisher': 'Activision'}

Read

def read():
    with app.app_context():
        table = Game.query.all()
    json_ready = [game.read() for game in table] # "List Comprehensions", for each user add user.read() to list
    return json_ready

read()
[{'id': 1,
  'name': 'Mario Party 9',
  'price': 169.0,
  'release_date': datetime.date(2012, 2, 3),
  'developer': 'NDcube',
  'publisher': 'Nintendo'},
 {'id': 2,
  'name': 'Legend of Zelda: Tears of the Kingdom',
  'price': 69.99,
  'release_date': datetime.date(2023, 5, 12),
  'developer': 'Nintendo Entertaining Planning and Development',
  'publisher': 'Nintendo'},
 {'id': 3,
  'name': 'Destiny 2',
  'price': 60.0,
  'release_date': datetime.date(2023, 3, 22),
  'developer': 'Bungie',
  'publisher': 'Activision'},
 {'id': 4,
  'name': 'Overwatch',
  'price': 60.0,
  'release_date': datetime.date(2016, 11, 20),
  'developer': 'Blizzard',
  'publisher': 'Activision'}]

Update

def update():
    # find the game to update
    name = input("Enter the name of the game to update: ")
    game = find_by_name(name)
    if not game:
        print("Game not found")
        return
    
    # print the current values
    print("Current values:")
    print(game.read())
    
    # prompt the user for new values, allowing them to skip
    new_name = input(f"Enter a new name [{game.name}]: ")
    if new_name:
        game.name = new_name
    
    new_price = input(f"Enter a new price [{game.price}]: ")
    if new_price:
        game.price = float(new_price)
    
    new_developer = input(f"Enter a new developer [{game.developer}]: ")
    if new_developer:
        game.developer = new_developer
    
    new_publisher = input(f"Enter a new publisher [{game.publisher}]: ")
    if new_publisher:
        game.publisher = new_publisher
    
    new_release_date = input(f"Enter a new release date (YYYY-MM-DD) [{game.release_date}]: ")
    if new_release_date:
        try:
            game.release_date = datetime.strptime(new_release_date, '%Y-%m-%d').date()
        except ValueError:
            print("Invalid date format. Date not updated.")
    
    # update the game in the database
    with app.app_context():
        try:
            updated_game = game.update()
            print("Updated values:")
            print(updated_game.read())
        except:
            print("Error updating game")
update()
Current values:
{'id': 4, 'name': 'Overwatch', 'price': 60.0, 'release_date': datetime.date(2016, 11, 20), 'developer': 'Blizzard', 'publisher': 'Activision'}
Updated values:
{'id': 4, 'name': 'Overwatch', 'price': 60.0, 'release_date': datetime.date(2016, 11, 21), 'developer': 'Blizzard', 'publisher': 'Activision'}

Delete

def delete():
    name = input("Enter the name of the game to delete:")
    game = find_by_name(name)
    try:
        print("Found\n", game.read())
    except:
        print(f"Game with name {name} not found")
        return
    
    # confirm deletion
    confirm = input("Are you sure you want to delete this game? (y/n)")
    if confirm.lower() == 'y':
        with app.app_context():
            try:
                game.delete()
                print(f"Game with name {name} deleted")
            except:  # error raised if object not deleted
                print(f"Unknown error deleting game with name {name}")
    else:
        print(f"Deletion of game with name {name} cancelled")

delete()
Found
 {'id': 3, 'name': 'Destiny 2', 'price': 60.0, 'release_date': datetime.date(2023, 3, 22), 'developer': 'Bungie', 'publisher': 'Activision'}
Game with name Destiny 2 deleted

Menu

def menu():
    operation = input("Enter: (C)reate (R)ead (U)pdate or (D)elete")
    if operation.lower() == 'c':
        create()
    elif operation.lower() == 'r':
        read()
    elif operation.lower() == 'u':
        update()
    elif operation.lower() == 'd':
        delete()
    elif len(operation)==0: # Escape Key
        return
    else:
        print("Please enter c, r, u, or d") 
    menu() # recursion, repeat menu
        
try:
    menu() # start menu
except:
    print("Perform Jupyter 'Run All' prior to starting menu")
Created
 {'id': 5, 'name': 'Fall Guys', 'price': 4.99, 'release_date': datetime.date(2020, 4, 15), 'developer': 'Ubisoft', 'publisher': 'Activision'}