#StackBounty: #sql #ruby-on-rails SQL query rails, how to filter our current reservation

Bounty: 50

For an hotel app, I’m trying to filter out all available accommodations for a given arrival and departure date, so a user only sees these as options.

The way I currently go about it, is by identifying all unavailable accommodations first and then deducting them from all accommodations.

Question

When I want to edit a reservation, I would like to:

  • exclude the current reservation when evaluating available accommodations

==> so in @unavailable_accommodations, the reservation and its accommodation for the reservation.arrival and reservation.departure are not evaluated in the query statement

Is this possible, or how else can I achieve to only get available accommodations for a giver arrival and departure without taking the current reservation.accommodation into account?

Example desired outcome

  • Say reservation_1 books accommodation_1 from Jan 1 to Jan 2.
  • Then there is reservation_2 which books accommodation_1 from Jan 5 to Jan 6.
  • When I subsequently edit reservation_1 and alter the departure to Jan 6, accommodation_1 should not be marked as available as reservation_2 already booked this accommodation

Code

models

class Reservation < ApplicationRecord
  belongs_to :hotel
  belongs_to :accommodation
end

class Accommodation < ApplicationRecord
  belongs_to :accommodation_category
  has_many :reservations, dependent: :destroy
  accepts_nested_attributes_for :accommodation_category
end

class Hotel < ApplicationRecord
  has_many :accommodation_categories, dependent: :destroy
  has_many :accommodations, through: :accommodation_categories
  has_many :reservations, dependent: :destroy
end

Query

@unavailable_accommodations = Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival <= ? AND ? <= reservations.departure", arrival, departure)
.or(Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival >= ? AND ? >= reservations.departure", arrival, departure)).distinct

controller action


def accommodations_availability
#check if there was an accommodation for this reservation
    if !params[:reservation].nil?
      reservation = Reservation.find(params[:reservation])
      @prev_accommodation = reservation.accommodation
      @previous_cat = @prev_accommodation.accommodation_category
    end
    hotel = Hotel.includes(:accommodations).find(params[:id])
    arrival = Date.parse(accommodation_params[:arrival])
    departure = Date.parse(accommodation_params[:departure])
    time_span = arrival..departure

    #SQL statement
    @unavailable_accommodations = Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival <= ? AND ? <= reservations.departure", arrival, departure)
    .or(Accommodation.joins(:reservations).where(reservations: {hotel: hotel}).where("reservations.arrival >= ? AND ? >= reservations.departure", arrival, departure)).distinct


    @hotel_cats = hotel.accommodation_categories
    @hotel_accos = Accommodation.where(accommodation_category: @hotel_cats)
    @accommodations = @hotel_accos - @unavailable_accommodations
    @available_cats = []
    @accommodations.each do |acco|
      if !@available_cats.include? acco.accommodation_category
        @available_cats << acco.accommodation_category
      end
    end

    respond_to do |format|
      format.js
    end
  end


Get this bounty!!!

#StackBounty: #sql #ms-access Slow performing subquery

Bounty: 50

This query executes very slowly and I wonder if it can be improved?

We have an Access database split to front end / back end with around 50 users. BE is in a network folder and FE is on users’ hard drives.

Data entered into the FE is stored in FE tables until the user has finished inputting all the required data for a record. They then click a button to send the data to the BE in one go, to identical tables as in the FE. In the sql below the BE table is suffixed with ‘_Share’.

The table contains 2 keys: QuoteID and OptionID. There is a one-to-many between the two e.g.:

QuoteID   OptionID

1234      1
1234      2

3333      1
3333      2
3333      3

As they user works they are creating data for new Options to go with existing Quotes. What the code is doing is to check whether a QuoteID on the BE already has an OptionID created by the user on the FE, if not then the data for that OptionID is appended to the BE.

INSERT INTO T_Option_Category_Benefits_Share
SELECT T_Option_Category_Benefits.*, * 
FROM T_Option_Category_Benefits 
WHERE (((T_Option_Category_Benefits.QuoteID)=1971) 
AND ((T_Option_Category_Benefits.OptionID) 
NOT IN (SELECT T_Option_Category_Benefits_Share.OptionID FROM T_Option_Category_Benefits_Share WHERE T_Option_Category_Benefits_Share.QuoteID=1971)));

The key fields are not indexed. The BE table contains 18 columns with around 100k rows. The network is generally quite slow at busy times. We’re using Office 365 on Windows 10.


Get this bounty!!!

#StackBounty: #magento2 #database #magento2.3 #sql #sorting Magento 2: Multiple Product Type Not Sorting Due To Amasty Extension

Bounty: 50

I’m facing a problem due to Amasty Extension. I have a category which has 1 simple product and some configurable products, but when I try to sort them, simple product always comes first although configurable product did sort as I need but simple product always comes first here are some screenshots:

enter image description hereenter image description here

You can see I sort simple product on 5th position but it always comes first, so I try to debug and echo the Magento_Catalog/templates/product/list.phtml

$_productCollection = $block->getLoadedProductCollection();
echo get_class($_productCollection);
echo "<br>".$_productCollection->getSelect()->__toString();

And I got this query with class that goes to Amasty

AmastyShopbyModelResourceModelFulltextCollectionInterceptor

SELECT 
    `e`.*,
    `cat_index`.`position` AS `cat_index_position`,
    `price_index`.`price`,
    `price_index`.`tax_class_id`,
    `price_index`.`final_price`,
    IF(price_index.tier_price IS NOT NULL,
        LEAST(price_index.min_price,
                price_index.tier_price),
        price_index.min_price) AS `minimal_price`,
    `price_index`.`min_price`,
    `price_index`.`max_price`,
    `price_index`.`tier_price`,
    `stock_status_index`.`stock_status` AS `is_salable`
FROM
    `catalog_product_entity` AS `e`
        INNER JOIN
    `catalog_category_product_index_store1` AS `cat_index` ON cat_index.product_id = e.entity_id
        AND cat_index.store_id = 1
        AND cat_index.visibility IN (2 , 4)
        AND cat_index.category_id = 59
        INNER JOIN
    `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id
        AND price_index.website_id = '1'
        AND price_index.customer_group_id = '2'
        LEFT JOIN
    `cataloginventory_stock_status` AS `stock_status_index` ON e.entity_id = stock_status_index.product_id
        AND stock_status_index.website_id = 0
        AND stock_status_index.stock_id = 1
WHERE
    (e.entity_id IN ((SELECT 
            `cat`.`product_id`
        FROM
            `catalog_category_product_index_store1` AS `cat`
        WHERE
            (cat.category_id IN ('206')))))
ORDER BY `cat_index`.`position` ASC ,  `cat_index`.`position` ASC
LIMIT 18

I found out that WHERE is the problem here:

WHERE
    (e.entity_id IN ((SELECT 
            `cat`.`product_id`
        FROM
            `catalog_category_product_index_store1` AS `cat`
        WHERE
            (cat.category_id IN ('206')))))

So I replace this WHERE with INNER JOIN

INNER JOIN
    `catalog_category_product_index_store1` AS `cat` ON cat.product_id = e.entity_id
        AND cat.store_id = 1
        AND cat.visibility IN (2 , 4)
        AND cat.category_id IN ('206')

after that I got product sorting like this:
enter image description here

You can see with the INNER JOIN I got all the product at the exact position as I want it to be. So I need to apply it in Magneto and I found that class I mention before AmastyShopbyModelResourceModelFulltextCollection.php, I start debugging and found that this function made the WHERE query:

public function addIndexCategoriesFilter(array $categoriesFilter)
{
    foreach ($categoriesFilter as $conditionType => $values) {
        $categorySelect = $this->getConnection()->select()->from(
            ['cat' => $this->getTable('catalog_category_product_index')],
            'cat.product_id'
        )->where($this->getConnection()->prepareSqlCondition('cat.category_id', ['in' => $values]));
        $selectCondition = [
            $this->mapConditionType($conditionType) => $categorySelect
        ];
        $whereCondition = $this->getConnection()->prepareSqlCondition('e.entity_id', $selectCondition);
        $this->getSelect()->where($whereCondition);
        $this->requestBuilder->bind(Category::ATTRIBUTE_CODE, $values);
    }
    return $this;
}

I try to replace WHERE with INNER JOIN but I don’t know how to do that, please help me out with this.

Thank You…


Get this bounty!!!

#StackBounty: #sql #azure #azure-data-factory-2 #azure-data-flow Joining multiple tables in single join transformation in Data Flow (Az…

Bounty: 500

Lets take sample sql as:

    select a.a1
    from
    alice a,
    bob b,
    chris c,
    don d
    where 
    a.a1 = b.b1 ,
    and b.b1 = c.c1 ,
    and c.c1 = d.d1 ;

When creating Data Flow (Azure Data Factory v2) to handle inner joins in above query we need to add 2 different join transformation. Is there any other way to use single join transformation for these multiple inner joins ???

Above query is just a sample, typically there can be 10 to 30 joins in single query.


Get this bounty!!!

#StackBounty: #sql #performance #sqlite #database-performance #sqlperformance SQLite "LIKE" operator is very slow compared to…

Bounty: 50

When I am using the LIKE operator in SQLite, it is very slow compared to when I use the = instead.
It takes about 14ms with the = operator, but when I use LIKE, it takes about 440ms. I am testing this with DB Browser for SQLite. Here is the query that works fast:

SELECT re.ENTRY_ID, 
       GROUP_CONCAT(re.READING_ELEMENT, '§') AS read_element,
       GROUP_CONCAT(re.FURIGANA_BOTTOM, '§') AS furigana_bottom,
       GROUP_CONCAT(re.FURIGANA_TOP, '§') AS furigana_top,
       GROUP_CONCAT(re.NO_KANJI, '§') AS no_kanji,
       GROUP_CONCAT(re.READING_COMMONNESS, '§') AS read_commonness, 
       GROUP_CONCAT(re.READING_RELATION, '§') AS read_rel,
       GROUP_CONCAT(se.SENSE_ID, '§') AS sense_id, 
       GROUP_CONCAT(se.GLOSS, '§') AS gloss, 
       GROUP_CONCAT(se.POS, '§') AS pos, 
       GROUP_CONCAT(se.FIELD, '§') AS field,
       GROUP_CONCAT(se.DIALECT, '§') AS dialect, 
       GROUP_CONCAT(se.INFORMATION, '§') AS info 
FROM Jmdict_Reading_Element AS re LEFT JOIN 
     Jmdict_Sense_Element AS
     se ON re.ENTRY_ID = se.ENTRY_ID
WHERE re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Reading_Element WHERE READING_ELEMENT = 'example') OR 
      re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Sense_Element WHERE GLOSS = 'example')
 GROUP BY re.ENTRY_ID

The slows down when I change

WHERE re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Reading_Element WHERE READING_ELEMENT = 'example') OR 
re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Sense_Element WHERE GLOSS = 'example')

to

WHERE re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Reading_Element WHERE READING_ELEMENT LIKE 'example') OR 
re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Sense_Element WHERE GLOSS LIKE 'example')

I need to do this so that I can use wildcards e.g.

WHERE re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Reading_Element WHERE READING_ELEMENT LIKE 'example%') OR 
re.ENTRY_ID IN (SELECT ENTRY_ID FROM Jmdict_Sense_Element WHERE GLOSS LIKE 'example%')

Here is a link to the database itself:
https://www.mediafire.com/file/hyuymc84022gzq7/dictionary.db/file

Thanks


Get this bounty!!!

#StackBounty: #sql #sql-server Find number of days that intersect a given date range in a table of date ranges

Bounty: 50

I want to find the total number of days in a date range that overlap a table of date ranges.

For example, I have 7 days between 2 dates in the table below. I want to find the days between between them that also fall this date range: 2019-08-01 to 2019-08-30.

It should return 1 day.

This is the data source query:

SELECT LeaveId, UserId, StartDate, EndDate, Days
FROM TblLeaveRequest
WHERE UserId = 218
LeaveID     UserID      StartDate               EndDate                 Days
----------- ----------- ----------------------- ----------------------- -----------
22484       218         2019-07-26 00:00:00.000 2019-08-01 00:00:00.000 7


Get this bounty!!!

#StackBounty: #sql #oracle #oracle11g #common-table-expression #ms-query Oracle CTE failing in one computer

Bounty: 100

I have queries created in Microsoft Query to run in Excel with VBA.

They work in different computers but there’s one computer where it doesn’t work.

In that computer the queries still work except the ones that use CTEs.

A normal query like the following works:

SELECT
  TBL.COL
FROM
  DB.TBL TBL;

But when it has a subquery (CTE) like the following:

WITH
  SUBQUERY AS (
    SELECT
      TBL.COL
    FROM
      DB.TBL TBL
  )
SELECT
  SUBQUERY.COL
FROM
  SUBQUERY;

It runs but doesn’t retrieve any data.

It doesn’t even show the column name like it would if it worked but had 0 records returned.

The query shows the warning message:

SQL Query can’t be represented graphically. Continue anyway?

Which is normal and shows in any computer, but it also shows another warning message after:

SQL statement executed successfully.

Which only appears in that computer when it doesn’t work.

I need to be able to use them for the queries that I have made.

Using temporary tables would maybe work but I don’t have the permissions required to try.

I tried using inline views but they duplicate the data.


Get this bounty!!!

#StackBounty: #sql #concurrency #h2 Using H2 1.4 database can I write new rows if reading other rows

Bounty: 100

Using H2 1.4 database can I write new rows if reading other rows?

i.e if have 1000 rows in table, and have a SELECT query running that is getting primary key 1-10 would it be possible for an INSERT query to insert some new rows at same time, or would it have to wait for (all) the SELECT query on that table to finish?

What is the situation with an UPDATE of rows in table table but not being retrieved by any SELECT query?

I ask because with H2 1.3 I noticed that my application threads that accessed database seemed to spend a lot of time blocking, it seems better now I have upgraded to 1.4. But in my application that is multithreaded the threads are always dealing with different rows so it is important for me to better understanding how locking works in H2 (with the MV store, was previously using PAGE store with 1.3), and whether H2 can just lock individual rows when UPDATING or if it has to lock whole table.


Get this bounty!!!

#StackBounty: #python #object-oriented #sql #playing-cards #postgresql OOP Python Blackjack game with player accounts in PostgreSQL

Bounty: 50

This is an OOP version of Lastest version of my Blackjack game. Also, it now uses PostgreSQL as database.

import random
import typing as t
from enum import Enum
from functools import partial
import os
from getpass import getpass
from re import match
import bcrypt
import psycopg2
import attr


lock = partial(attr.s, auto_attribs=True, slots=True)
State = Enum("State", "IDLE ACTIVE STAND BUST")


def clear_console():
    os.system("cls" if os.name == "nt" else "clear")


def start_choice():
    while True:
        ans = input(
            "nWhat do you want to do?n[1] - Start playingn[2] - Display the topn> "
        )
        if ans in ("1", "2"):
            return ans == "1"


def ask_question(question):
    while True:
        print(f"{question} (y/n)?")
        ans = input("> ").casefold()
        if ans in ("y", "n"):
            return ans == "y"


def ask_bet(budget):
    clear_console()
    print(f"Money: ${budget}")
    print("How much money do you want to bet?")
    while True:
        money_bet = input("> ")
        try:
            cash_bet = int(money_bet)
        except ValueError:
            cash_bet = -1
        if budget >= cash_bet > 0:
            return cash_bet
        print("Please input a valid bet.")


def get_user_credentials():
    clear_console()
    while True:
        email = input("Email address (max. 255 chars.):n> ")
        password = getpass("Password (max. 1000 chars.):n> ").encode("utf8")
        hashed_pw = bcrypt.hashpw(password, bcrypt.gensalt()).decode("utf8")
        if len(email) < 255 and len(password) < 1000:
            if match(r"[^@]+@[^@]+.[^@]+", email):
                return email, password, hashed_pw
            print("Please input a valid email address.")


def build_deck():
    suits = ["Hearts", "Clubs", "Diamonds", "Spades"]
    values = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
    cards = [Card(value, suit) for value in values for suit in suits]
    return cards


@lock
class Card:

    value: str
    suit: str

    def score(self):
        if self.value in "JQK":
            return 10
        elif self.value == "A":
            return 1
        else:
            return int(self.value)

    def __str__(self):
        return f"{self.value} of {self.suit}"


@lock
class Shoe:

    cards: t.List[Card] = attr.ib(factory=build_deck)

    def shuffle(self):
        random.shuffle(self.cards)

    def draw_card(self):
        return self.cards.pop()

    def __str__(self):
        cards = [str(c) for c in self.cards]
        return str(cards)


@lock
class Hand:
    # A collection of cards that a player get from the dealer in a game
    cards: t.List[Card] = attr.ib(default=[])

    def add(self, card):
        self.cards.append(card)

    def score(self):
        # Value of cards at hand
        total = sum(card.score() for card in self.cards)

        if any(card.value == "A" for card in self.cards) and total <= 11:
            total += 10

        return total

    def __str__(self):
        return "{} ({})".format(
            "".join("[{}]".format(card.value) for card in self.cards), self.score()
        )


@lock
class Player:

    budget: int  # Number of money for bets
    bet: int = attr.ib(default=None)  # Money bet
    hand: Hand = attr.ib(factory=Hand)  # Player's hand
    state: State = attr.ib(default=State.IDLE)  # can be IDLE, ACTIVE, STAND or BUST

    def player_bet(self):
        if self.is_broke():
            raise Exception("Unfortunately you don't have any money.")
        self.bet = ask_bet(self.budget)

    """ Update self.state after self.hit
        If player busted, self.state = State.BUST, etc.
    """

    def update(self):
        hand_score = self.hand.score()
        if hand_score > 21:
            self.state = State.BUST
        elif hand_score == 21:
            self.state = State.STAND
        else:
            self.state = State.ACTIVE

    def is_busted(self):
        return self.state == State.BUST

    def is_standing(self):
        return self.state == State.STAND

    def is_idle(self):
        return self.state == State.IDLE

    def is_broke(self):
        return self.budget == 0

    def hit(self, dealer):
        # Ask dealer to add a card to the hand (at their turn)
        card = dealer.draw_card()
        self.hand.add(card)

    def play(self, dealer):
        if ask_question("Do you want to hit"):
            # Player hits
            self.hit(dealer)
            self.update()
        else:
            self.state = State.STAND

    def __str__(self):
        return f"Player Info:nBudget: {self.budget}nMoney bet: {self.bet}nHand: {self.hand}"


@lock
class Dealer:

    shoe: Shoe = attr.ib(factory=Shoe)
    hand: Hand = attr.ib(factory=Hand)
    state: State = attr.ib(default=State.IDLE)

    def draw_card(self):  # Delegate method
        card = self.shoe.draw_card()
        return card

    def hit(self):
        card = self.draw_card()
        self.hand.add(card)

    def update(self):
        hand_score = self.hand.score()
        if hand_score > 21:
            self.state = State.BUST
        elif hand_score >= 17:
            self.state = State.STAND
        else:
            self.state = State.ACTIVE

    def is_busted(self):
        return self.state == State.BUST

    def is_standing(self):
        return self.state == State.STAND

    def is_idle(self):
        return self.state == State.IDLE

    def play(self):
        if self.hand.score() < 17:
            self.hit()
            self.update()

    """ In this method, the dealer and player enter a loop
        In which the player hits a card from the dealer until it stands or busts
    """

    def deal(self, player, game):
        while True:
            player.play(self)
            game.display_info()
            if player.is_busted() or player.is_standing():
                break

    def display_cards(self, player, game):
        if game.is_finished():
            return f"Dealer Info:nHand:{self.hand}"
        elif player.state == State.ACTIVE:
            return f"Dealer Info:nHand: [{self.hand.cards[0]}][?]"


@lock
class Database:

    sql_id: int = attr.ib(default=None)
    email: str = attr.ib(default=None)
    password: str = attr.ib(default=None)
    hashed_pw: str = attr.ib(default=None)
    budget: int = attr.ib(default=None)
    conn: t.Any = attr.ib(
        default=psycopg2.connect(
            dbname="blackjack", user="postgres", password="12344321", host="localhost"
        )
    )
    cur: t.Any = attr.ib(default=None)

    def check_account(self):
        self.cur.execute("SELECT id FROM users WHERE email=%s", (self.email,))
        return bool(self.cur.fetchone())

    def login(self):
        self.cur.execute("SELECT password FROM users WHERE email=%s", (self.email,))
        credentials = self.cur.fetchone()
        correct_hash = credentials[0].encode("utf8")
        if bcrypt.checkpw(self.password, correct_hash):
            print("You have successfully logged-in!")
        else:
            raise Exception("You have failed logging-in!")

    def register(self):
        self.cur.execute(
            "INSERT into users (email, password) VALUES (%s, %s)",
            (self.email, self.hashed_pw),
        )

    def initialize(self):
        with self.conn:
            self.email, self.password, self.hashed_pw = get_user_credentials()
            self.cur = self.conn.cursor()
            checked = self.check_account()
            if checked:
                self.login()
            else:
                self.register()
                print("You have successfully registered and received $1000 as a gift!")
            self.cur.execute(
                "SELECT ID, budget FROM users WHERE email=%s", (self.email,)
            )
            sql_id_budget = self.cur.fetchone()
            self.sql_id = sql_id_budget[0]
            self.budget = sql_id_budget[1]

    def display_top(self):
        self.cur.execute("SELECT email, budget FROM users ORDER BY budget DESC")
        top = self.cur.fetchall()
        places = range(1, len(top) + 1)
        for (a, b), i in zip(top, places):
            print(f"{i}. {a} - ${b}")

    def update_budget(self):
        self.cur.execute(
            "UPDATE users SET budget=%s WHERE id=%s", (self.budget, self.sql_id)
        )
        self.conn.commit()


@lock
class Game:

    player: Player
    dealer: Dealer = attr.ib(factory=Dealer)

    def reset_attributes(self):
        self.player.hand.cards = []
        self.player.state = State.IDLE
        self.dealer.hand.cards = []
        self.dealer.state = State.IDLE
        self.dealer.shoe = Shoe()

    def open(self):

        self.player.player_bet()

        self.dealer.shoe.shuffle()

        c1 = self.dealer.draw_card()
        c2 = self.dealer.draw_card()
        self.player.hand = Hand([c1, c2])
        self.player.update()  # Update player state

        # The dealer is the last one to get cards
        c1 = self.dealer.draw_card()
        c2 = self.dealer.draw_card()
        self.dealer.hand = Hand([c1, c2])
        self.dealer.update()

        self.display_info()

    def is_finished(self):
        if self.dealer.hand.score() >= 21:
            return True
        if self.player.is_busted() or self.player.is_standing():
            return True

    """ Pay/charge the player according to cards result
        Reset hands, states, shoe
    """

    def close(self):
        dealer_score = self.dealer.hand.score()
        if not self.player.is_busted():

            if self.dealer.state == State.BUST:
                self.player.budget += self.player.bet * 2
            else:
                if self.player.hand.score() < dealer_score:
                    self.player.budget -= self.player.bet
                elif self.player.hand.score() > dealer_score:
                    self.player.budget += self.player.bet * 2
        else:
            self.player.budget -= self.player.bet

        self.display_info()

    def run(self):
        # Run a full game, from open() to close()
        self.open()

        # If the dealer has a blackjack, close the game
        if self.is_finished():
            self.close()
            return

        # The dealer deals with the player
        self.dealer.deal(self.player, self)

        # Now the dealer's turn to play ...
        while True:
            self.dealer.play()
            if self.dealer.is_busted() or self.dealer.is_standing():
                break

        self.close()

    def display_info(self):
        clear_console()
        print(f"{self.player}n")
        print(f"{self.dealer.display_cards(self.player, self)}n")
        player_score = self.player.hand.score()
        dealer_score = self.dealer.hand.score()
        if player_score == 21:
            print("Blackjack! You won!")
        elif dealer_score == 21:
            print("Dealer has got a blackjack. You lost!")
        elif self.player.is_busted():
            print("Busted! You lost!")
        elif self.player.is_standing():
            if self.dealer.is_busted():
                print("Dealer busted! You won!")
            elif player_score > dealer_score:
                print("You beat the dealer! You won!")
            elif player_score < dealer_score:
                print("Dealer has beaten you. You lost!")
            else:
                print("Push. Nobody wins or losses.")


def main():
    database = Database()
    database.initialize()
    if start_choice():
        player = Player(database.budget)
        game = Game(player)
        playing = True
        while playing:
            game.run()
            database.budget = player.budget
            database.update_budget()
            playing = ask_question("nDo you want to play again")
            if playing:
                game.reset_attributes()
            else:
                database.cur.close()
    else:
        database.display_top()


if __name__ == "__main__":
    main()


Get this bounty!!!