Sunday, 15 April 2018

Python - OOPS Basics-eg1 - Day 25(4 days later)

  • simple program on bank account concept,based on oops
  •   
    import datetime
    import pytz
    class Account:
    
        #this will be static method,ie it will be common for all instances(ie the class)
        #so while accessing it no need of using self
        @staticmethod
        def _current_time():
            utc_time = datetime.datetime.utcnow()
            return pytz.utc.localize(utc_time)
    
    
    
        def __init__(self,name,_balance):
            self._name =name
            self._transactiondetails_list = [(Account._current_time(), _balance)]
            self._balance = _balance
            print("Account Created for {}".format(self._name))
            self.showbalance()
    
        def deposit(self,amount):
            self._balance+=amount
            self.showbalance()
            self._transactiondetails_list.append((Account._current_time(), amount))
            # self.transactiondetails_list.append((pytz.utc.localize(datetime.datetime.utcnow()),amount))
            # print(self.transactiondetails_list)
    
        def withdraw(self,amount):
            if(0 < amount<=self._balance):
                self._balance-=amount
                self._transactiondetails_list.append((Account._current_time(), -amount))
            else:
                print("Amount should be greater than 0 and lesser than available balance")
            self.showbalance()
    
        def showbalance(self):
            print('Balance: ', self._balance)
    
        def showtransdetails(self):
            for date, amount in self._transactiondetails_list:
                if amount > 0:
                    tran_type ='Deposited'
                else:
                    tran_type ='Withdrwan'
                    amount*=-1
                print("{:6} {} on {} (local time was {})".format(amount,tran_type,date,date.astimezone()))
    
    udai = Account('udai',1000)
    #udai.withdraw(100)
    # udai.withdraw(200)
    # udai.deposit(200)
    # #we can update the balance variable to whatever we want outside of the class,so we can rename
    # #to _balance,which will also dont restrict to change , but user can know that
    # #it is for internal purpose and shouldn't be modified,similarly for the name and list variables
    # #which should not be modified after the instantiation
    # # udai.balance=0
    # udai.showbalance()
    # udai.showtransdetails()
    
    #its better not to mess with '_' and '__' objects which will produce strange results
    udai.showbalance()
    udai._balance = 10
    udai.showbalance()
    print('*'*40)
    print(udai.__dict__)
    print(Account.__dict__)
    udai.__balance = 49
    udai.showbalance()
    udai.showbalance()
    print(udai.__dict__)
    print(Account.__dict__)
     
    

    Python - OOPS Basics - Day 25(4 days later)

  • Class:template for creating objects.All objects created using the same class will have the same charecteristics Objects:an instance of a class Instantiate:Create a Instance of a class Method:a funtion defined in a class Attribute:a variable bound to a instance of a class
  •   
    #everything is objects in python
    #take away : class and objects
    
    # a = 1
    # b = 3
    # print (a + b)
    # print (a.__add__(b))
    #so + is same as __add__ ,if u ctrl right click it will goto the same definition
    
    class kettle (object):
    
        power_source = 'fuel'
    
        def __init__(self,make,price):
            self.make = make
            self.price = price
            self.on = False
    
        def switch_on(self):
            self.on = True
    
    kenwoodobj = kettle('kenwood',25)
    hamilton = kettle('hamilton',30)
    
    print(kenwoodobj.make)
    print(hamilton.make)
    print(hamilton.price)
    hamilton.make = 'Hamiltoon'
    print(hamilton.make)
    print(kenwoodobj)
    
    print ('{}={},{}={}'.format(kenwoodobj.make,kenwoodobj.price,hamilton.make,hamilton.price))
    kenwoodobj1 = kenwoodobj
    print(id(kenwoodobj1))
    print(id(kenwoodobj))
    print(id(hamilton))
    print(id(hamilton.make))
    
    #we can call the object by
    #classname.objectname(instancename)
    #or
    #instancename.objectname()
    kettle.switch_on(hamilton)
    print(hamilton.make)
    print(hamilton.on)
    hamilton.on = False
    print(hamilton.on)
    hamilton.switch_on()
    print(hamilton.on)
    
    #this is called as instance variable,variable is only for this instance,not for the entire instances of the
    #class
    kenwoodobj.power = 1.5
    print(kenwoodobj.power)
    #if we try accessing the same variable for different instance,it will throw error
    # print(hamilton.power)
    
    print (kettle.power_source)
    print (kenwoodobj.power_source)
    print (hamilton.power_source)
    
    print(kettle.__dict__)
    print(kenwoodobj.__dict__)
    print(hamilton.__dict__)
    
    print ('*' * 80)
    
    # kettle.power_source = 'atomic'
    
    print (kettle.power_source)
    print (kenwoodobj.power_source)
    print (hamilton.power_source)
    
    print(kettle.__dict__)
    print(kenwoodobj.__dict__)
    print(hamilton.__dict__)
    
    print ('/' * 80)
    
    #if we assign the value for the calss attribute instance,it becomes instance vriable and remains
    #unaffected for the class and other instances
    kenwoodobj.power_source = 'gas'
    
    print (kettle.power_source)
    print (kenwoodobj.power_source)
    print (hamilton.power_source)
    
    print(kettle.__dict__)
    print(kenwoodobj.__dict__)
    print(hamilton.__dict__)
    
    print ('*' * 80)
    hamilton.power_source = 'fossil fuel'
    
    print (kettle.power_source)
    print (kenwoodobj.power_source)
    print (hamilton.power_source)
    
    print(kettle.__dict__)
    print(kenwoodobj.__dict__)
    print(hamilton.__dict__)
    
    hamilton.power_source = 'fuel'
    
    print (kettle.power_source)
    print (kenwoodobj.power_source)
    print (hamilton.power_source)
    
    print(kettle.__dict__)
    print(kenwoodobj.__dict__)
    print(hamilton.__dict__)
    
    print ('@' * 80)
    
    kettle.power_source = 'fuel'
    
    print (kettle.power_source)
    print (kenwoodobj.power_source)
    print (hamilton.power_source)
    
    print(kettle.__dict__)
    print(kenwoodobj.__dict__)
    print(hamilton.__dict__)
     
    
  • this will explain how a basic program document has to be written
  •   
    #this will explain you how to document a program(DocString)
    class song:
        """
        class to represent a song
    
        Attributes:
            title():The tile of the song
            artist(Artist):An artist object representing the songs creator
            duration (int):The duration of the song in seconds.May be Zero
        """
        def __int__(self,title,artist,duration=0):
            """song init method
            Args:
                title(str):Intialises the 'title' attribute
                artist(Artist):An artist object representing the songs creator
                duration (optional int):initialise value to 'duration' attribute
                        will be defaulted to zero if not specified.
    
    
            """
            self.title = title
            self.artist = artist
            self.duration = duration
     
    

    Python - scope and recursive function - Day 25(4 days later)

  • this will explain the variable's scope.
  •   
    #take way:read the document related to local,nonlocal,global
    #know what is LEGB - Local Enclosing Global Builtins
    #below example will illustrate the variable and the scope of it
    
    
    # def spam1():
    #     def spam2():
    #         def spam3():
    #             z = ' even more spam'
    #             print('3 {}'.format(locals()))
    #             return z
    #         y = 'more spam '
    #         y+= spam3()
    #         print('2 {}'.format(locals()))
    #         return y
    #     x = 'spam '
    #     x+= spam2()
    #     print('1 {}'.format(locals()))
    #     print(x)
    
    def spam1():
        def spam2():
            def spam3():
                # y = 'test'
                z = ' even' + y
                print('3 {}'.format(locals()))
                return z
            y = ' more'+x
            y+= spam3()
            print('2 {}'.format(locals()))
            return y
        x = 'spam'
        x+= spam2()
        # we can't write like this x = 'spam' + spam2(),since spam2 function first expects x
        # it will throw unreferenced variable error if we code like that
        print('1 {}'.format(locals()))
        print(x)
    
    print(spam1())
    print(locals())
    print(globals())
     
    
  • this will explain how the recursive funtion can be made use of
  •   
    #recursive function,function that calls itself again and again
    #factorial
    
    def factorial(n):
        result = 1
        if n>1:
            for i in range (1,n+1):
                result = result * i
        return result
    
    def factorialrec(n):
        #n factorial can also be defined as n * (n-1)!
        if n<=1:
            return 1
        else:
            return n * factorialrec(n-1)
    
    def fibonaccirec(n):
        # Fn = Fn-1 + Fn-2
        if n<2:
            return n
        else:
            return fibonaccirec(n-1)+fibonaccirec(n-2)
    
    def fibonacci(n):
        if n == 0:
            return 0
        if n == 1:
            return 1
        elif n==2:
            return 1
        else:
            n_minus1 = 1
            n_minus2 = 0
            for i in range(1,n):
                result = n_minus1+n_minus2
                n_minus2 = n_minus1
                n_minus1 = result
            return result
    
    
    
    
    # for x in range (1,130):
    #     print(x , factorial(x))
    
    # for x in range (1,130):
    #     print(x , factorialrec(x))
    
    # here use of the recursive funtion in calculating the fibonaaci
    #might slow downb the process,so we can go for direct method
    
    # for x in range (1,36):
    #     print(x , fibonaccirec(x))
    
    #below direct method will be fast
    for x in range (1,36):
        print(x , fibonacci(x))
     
    

    Monday, 9 April 2018

    Python - using underscore - Day 24

      
    #there is nothing like private or protected concept in python
    #if we want to treat something as private we can use underscore '_'
    # in front of the name,although it wont have any programming influence,
    # but for the users understanding,also the objects starting with '_' won't be
    # displayed if we use import *,although we can access using the modulename.objectname
    # import blackjacktest1
    # g = sorted(globals())
    # for x in g:
    #     print(x)
    # for x in globals():
    #     print(x)
    # print (__name__)
    # blackjacktest1.play()
    
    #if you rename by prefexing any of the funtion with '_' and check the below loop will not return
    #those funtions or objects
    
    from blackjacktest1 import *
    g = sorted(globals())
    for x in g:
        print(x)
    
    #we can use '_' or '__' as variable name, thoughh it is not the proper way of naming variable
    _ = 'a'
    print(_)
    __ = 'ab'
    print(__)
    
    personaldetails =('udai',23,'welcome')
    name,_,__ = personaldetails
    print(name,_,__)
     
    

    Sunday, 8 April 2018

    Python - import challenge - blackjack game - Day 23


  • if we directly import the module it will execute w/o users control..ie it will execute immediately after the import statement which is not intended..
  • here few changes are made to run the module from other code..ie by importing it and calling the functionality whenever needed
  • we can make use of the __name__ to do this

  •   
    #this is extension of blackjack game to include the new game button and shuffle button
    
    import tkinter as tkinter
    import random
    
    try:
        import tkinter
    except ImportError:  # python 2
        import Tkinter as tkinter
    def load_images(card_images):
        suits=['heart','club','diamond','spade']
        face_cards=['jack','queen','king']
    
        if tkinter.TkVersion >= 8.6:
            extension = 'png'
        else:
            extension = 'ppm'
        #for each suit retrieve the image for the cards
        for suit in suits:
            #first the number cards 1 to 10
            for card in range(1,11):
                name = 'cards/{}_{}.{}'.format(str(card),suit,'png')
                image = tkinter.PhotoImage(file = name)
                card_images.append((card,image))
            #next the Face Cards
            for card in face_cards:
                name = 'cards/{}_{}.{}'.format(str(card),suit,'png')
                image = tkinter.PhotoImage(file = name)
                card_images.append((10,image))
    
    def deal_card(frame):
        #pop the next card of the top of the deck
        next_card= deck.pop(0)
        #if the player keeps on playing new game then all the cards will be used so
        deck.append(next_card)
        #add the image to the label and display the label
        tkinter.Label(frame,image=next_card[1],relief = 'raised').pack(side = 'left')
        #now return the cards face value
        return next_card
    
    
    def score_hand(hand):
        # Calculate the total score of all cards in the list.
        # Only one ace can have the value 11, and this will be reduce to 1 if the hand would bust.
        score = 0
        ace = False
        for next_card in hand:
            card_value = next_card[0]
            if card_value == 1 and not ace:
                ace = True
                card_value = 11
            # score += card_value
            score = score + card_value
            # if we would bust, check if there is an ace and subtract 10
            if score > 21 and ace:
                # score -= 10
                score = score - 10
                ace = False
        return score
    
    def deal_dealer():
        dealer_score= score_hand(dealer_hand)
        while 0 < dealer_score <17:
            dealer_hand.append(deal_card(dealer_card_frame))
            dealer_score= score_hand(dealer_hand)
            dealer_score_label.set(dealer_score)
    
        player_score = score_hand(player_hand)
        if player_score>21:
            resulttext.set('Dealer Wins!')
        elif dealer_score > 21 or dealer_score player_score:
            resulttext.set('Dealer Wins!')
        else:
            resulttext.set('Draw!')
    
        # player_score_label.set(player_score)
        # if player_score>21:
        #     resulttext.set ('Dealer Wins')
    
    
    # def deal_player():
    #     deal_card(player_card_frame)
    
    def deal_player():
        player_hand.append(deal_card(player_card_frame))
        player_score= score_hand(player_hand)
    
        player_score_label.set(player_score)
        if player_score>21:
            resulttext.set ('Dealer Wins')
        # global player_score
        # global player_ace
        # card_value = deal_card(player_card_frame)[0]
        # if card_value ==1 and not player_ace:
        #     player_ace = True
        #     card_value = 11
        # player_score = player_score + card_value
        # # if we would bust,check if there is an ace and subtract
        # if player_score>21 and player_ace:
        #     player_score = player_score - 10
        #     player_ace = False
        # player_score_label.set(player_score)
        # if player_score>21:
        #     resulttext.set("Dealer Wins")
        # print(locals())
    
    def new_game():
        global dealer_card_frame
        global player_card_frame
        global dealer_hand
        global player_hand
        # embedded frame to hold the card images
        dealer_card_frame.destroy()
        dealer_card_frame = tkinter.Frame(card_frame, background='green')
        dealer_card_frame.grid(row=0, column=1, sticky='ew', rowspan=2)
        # embedded frame to hold the card images
        player_card_frame.destroy()
        player_card_frame = tkinter.Frame(card_frame, background="green")
        player_card_frame.grid(row=2, column=1, sticky='ew', rowspan=2)
    
        resulttext.set("")
    
        # Create the list to store the dealer's and player's hands
        dealer_hand = []
        player_hand = []
    
        deal_player()
        dealer_hand.append(deal_card(dealer_card_frame))
        dealer_score_label.set(score_hand(dealer_hand))
        deal_player()
    
    def shuffle():
        random.shuffle(deck)
    
    
    
    def play():
        deal_player()
        dealer_hand.append(deal_card(dealer_card_frame))
        dealer_score_label.set(score_hand(dealer_hand))
        deal_player()
        mainwindow.mainloop()
    
    
    mainwindow = tkinter.Tk()
    #setup the screens and frame for the dealer and the player
    mainwindow.title("blackjack")
    mainwindow.geometry("640x480")
    mainwindow.configure(background = "green")
    
    resulttext = tkinter.StringVar()
    result = tkinter.Label(mainwindow,textvariable = resulttext)
    result.grid(row=0,column=0,columnspan=3)
    
    card_frame= tkinter.Frame(mainwindow,relief = 'sunken',borderwidth = 1,background = 'green')
    card_frame.grid(row=1,column=0,sticky = 'ew',columnspan = 3,rowspan=2)
    
    dealer_score_label = tkinter.IntVar()
    tkinter.Label(card_frame,text = 'Dealer',background ='green',fg='white').grid(row=0,column=0)
    tkinter.Label(card_frame,textvariable = dealer_score_label,background ='green',fg='white').grid(row=1,column=0)
    
    #embedded Frame hold the card images
    dealer_card_frame=tkinter.Frame(card_frame,background = 'green')
    dealer_card_frame.grid(row=0,column=1,sticky='ew',rowspan=2)
    
    
    player_score_label = tkinter.IntVar()
    tkinter.Label(card_frame,text = 'Player',background ='green',fg='white').grid(row=2,column=0)
    tkinter.Label(card_frame,textvariable = player_score_label,background ='green',fg='white').grid(row=3,column=0)
    #embedded Frame hold the card images
    player_card_frame=tkinter.Frame(card_frame,background = 'green')
    player_card_frame.grid(row=2,column=1,sticky='ew',rowspan=2)
    
    button_frame = tkinter.Frame(mainwindow)
    button_frame.grid(row=3,column=0,columnspan = 3,sticky = 'w')
    
    dealer_button=tkinter.Button(button_frame,text = 'Dealer',command = deal_dealer)
    dealer_button.grid(row=0,column=0)
    
    player_button=tkinter.Button(button_frame,text = 'Player',command = deal_player)
    player_button.grid(row=0,column=1)
    
    new_game_button=tkinter.Button(button_frame,text = 'New Game',command = new_game)
    new_game_button.grid(row=0,column=2)
    
    shuffle_button = tkinter.Button(button_frame, text="Shuffle", command=shuffle)
    shuffle_button.grid(row=0, column=3)
    
    #load cards
    cards = []
    load_images(cards)
    # print(cards)
    # print(id(cards))
    #create a new deck of cards and shuffle them
    deck = list(cards) + list(cards) + list(cards)
    shuffle()
    
    # Create the list to store the dealer's and player's hands
    dealer_hand = []
    player_hand = []
    
    if __name__ == '__main__':
        play()
    
    
     
    
  • we can import by using the code like below one
  •   
    import blackjacktest1
    print (__name__)
    blackjacktest1.play()
     
    

    Python - function challenge - blackjack game extension - Day 23


  • #this is extension of blackjack game to include the new game button and shuffle button

  •   
    #this is extension of blackjack game to include the new game button and shuffle button
    
    import tkinter as tkinter
    import random
    
    try:
        import tkinter
    except ImportError:  # python 2
        import Tkinter as tkinter
    def load_images(card_images):
        suits=['heart','club','diamond','spade']
        face_cards=['jack','queen','king']
    
        if tkinter.TkVersion >= 8.6:
            extension = 'png'
        else:
            extension = 'ppm'
        #for each suit retrieve the image for the cards
        for suit in suits:
            #first the number cards 1 to 10
            for card in range(1,11):
                name = 'cards/{}_{}.{}'.format(str(card),suit,'png')
                image = tkinter.PhotoImage(file = name)
                card_images.append((card,image))
            #next the Face Cards
            for card in face_cards:
                name = 'cards/{}_{}.{}'.format(str(card),suit,'png')
                image = tkinter.PhotoImage(file = name)
                card_images.append((10,image))
    
    def deal_card(frame):
        #pop the next card of the top of the deck
        next_card= deck.pop(0)
        #if the player keeps on playing new game then all the cards will be used so
        deck.append(next_card)
        #add the image to the label and display the label
        tkinter.Label(frame,image=next_card[1],relief = 'raised').pack(side = 'left')
        #now return the cards face value
        return next_card
    
    
    def score_hand(hand):
        # Calculate the total score of all cards in the list.
        # Only one ace can have the value 11, and this will be reduce to 1 if the hand would bust.
        score = 0
        ace = False
        for next_card in hand:
            card_value = next_card[0]
            if card_value == 1 and not ace:
                ace = True
                card_value = 11
            # score += card_value
            score = score + card_value
            # if we would bust, check if there is an ace and subtract 10
            if score > 21 and ace:
                # score -= 10
                score = score - 10
                ace = False
        return score
    
    def deal_dealer():
        dealer_score= score_hand(dealer_hand)
        while 0 < dealer_score <17:
            dealer_hand.append(deal_card(dealer_card_frame))
            dealer_score= score_hand(dealer_hand)
            dealer_score_label.set(dealer_score)
    
        player_score = score_hand(player_hand)
        if player_score>21:
            resulttext.set('Dealer Wins!')
        elif dealer_score > 21 or dealer_score player_score:
            resulttext.set('Dealer Wins!')
        else:
            resulttext.set('Draw!')
    
        # player_score_label.set(player_score)
        # if player_score>21:
        #     resulttext.set ('Dealer Wins')
    
    
    # def deal_player():
    #     deal_card(player_card_frame)
    
    def deal_player():
        player_hand.append(deal_card(player_card_frame))
        player_score= score_hand(player_hand)
    
        player_score_label.set(player_score)
        if player_score>21:
            resulttext.set ('Dealer Wins')
        # global player_score
        # global player_ace
        # card_value = deal_card(player_card_frame)[0]
        # if card_value ==1 and not player_ace:
        #     player_ace = True
        #     card_value = 11
        # player_score = player_score + card_value
        # # if we would bust,check if there is an ace and subtract
        # if player_score>21 and player_ace:
        #     player_score = player_score - 10
        #     player_ace = False
        # player_score_label.set(player_score)
        # if player_score>21:
        #     resulttext.set("Dealer Wins")
        # print(locals())
    
    def new_game():
        global dealer_card_frame
        global player_card_frame
        global dealer_hand
        global player_hand
        # embedded frame to hold the card images
        dealer_card_frame.destroy()
        dealer_card_frame = tkinter.Frame(card_frame, background='green')
        dealer_card_frame.grid(row=0, column=1, sticky='ew', rowspan=2)
        # embedded frame to hold the card images
        player_card_frame.destroy()
        player_card_frame = tkinter.Frame(card_frame, background="green")
        player_card_frame.grid(row=2, column=1, sticky='ew', rowspan=2)
    
        resulttext.set("")
    
        # Create the list to store the dealer's and player's hands
        dealer_hand = []
        player_hand = []
    
        deal_player()
        dealer_hand.append(deal_card(dealer_card_frame))
        dealer_score_label.set(score_hand(dealer_hand))
        deal_player()
    
    def shuffle():
        random.shuffle(deck)
    
    mainwindow = tkinter.Tk()
    
    #setup the screens and frame for the dealer and the player
    mainwindow.title("blackjack")
    mainwindow.geometry("640x480")
    mainwindow.configure(background = "green")
    
    resulttext = tkinter.StringVar()
    result = tkinter.Label(mainwindow,textvariable = resulttext)
    result.grid(row=0,column=0,columnspan=3)
    
    card_frame= tkinter.Frame(mainwindow,relief = 'sunken',borderwidth = 1,background = 'green')
    card_frame.grid(row=1,column=0,sticky = 'ew',columnspan = 3,rowspan=2)
    
    dealer_score_label = tkinter.IntVar()
    tkinter.Label(card_frame,text = 'Dealer',background ='green',fg='white').grid(row=0,column=0)
    tkinter.Label(card_frame,textvariable = dealer_score_label,background ='green',fg='white').grid(row=1,column=0)
    
    #embedded Frame hold the card images
    dealer_card_frame=tkinter.Frame(card_frame,background = 'green')
    dealer_card_frame.grid(row=0,column=1,sticky='ew',rowspan=2)
    
    
    player_score_label = tkinter.IntVar()
    tkinter.Label(card_frame,text = 'Player',background ='green',fg='white').grid(row=2,column=0)
    tkinter.Label(card_frame,textvariable = player_score_label,background ='green',fg='white').grid(row=3,column=0)
    #embedded Frame hold the card images
    player_card_frame=tkinter.Frame(card_frame,background = 'green')
    player_card_frame.grid(row=2,column=1,sticky='ew',rowspan=2)
    
    button_frame = tkinter.Frame(mainwindow)
    button_frame.grid(row=3,column=0,columnspan = 3,sticky = 'w')
    
    dealer_button=tkinter.Button(button_frame,text = 'Dealer',command = deal_dealer)
    dealer_button.grid(row=0,column=0)
    
    player_button=tkinter.Button(button_frame,text = 'Player',command = deal_player)
    player_button.grid(row=0,column=1)
    
    new_game_button=tkinter.Button(button_frame,text = 'New Game',command = new_game)
    new_game_button.grid(row=0,column=2)
    
    shuffle_button = tkinter.Button(button_frame, text="Shuffle", command=shuffle)
    shuffle_button.grid(row=0, column=3)
    
    #load cards
    cards = []
    load_images(cards)
    # print(cards)
    # print(id(cards))
    #create a new deck of cards and shuffle them
    deck = list(cards) + list(cards) + list(cards)
    shuffle()
    
    # Create the list to store the dealer's and player's hands
    dealer_hand = []
    player_hand = []
    
    new_game()
    
    mainwindow.mainloop()
    
     
    

    Saturday, 7 April 2018

    Python - function challenge - blackjack game - Day 22(after 1 day)


  • first we will download the cards image from the svg online or search in github
  • then extract and place those file in the project folder

  •   
    #this program explains how to achieve the blackjack game
    #the key points to note here are
    #pop funtion,using the same code of function to avoid repetition
    #load images from file to frame,shuffling of cards,calculating scores
    #then use of the global keyword to avoiding shadowing of the global variable inside the function
    
    import tkinter as tkinter
    import random
    
    def load_images(card_images):
        suits=['heart','club','diamond','spade']
        face_cards=['jack','queen','king']
    
        #for each suit retrieve the image for the cards
        for suit in suits:
            #first the number cards 1 to 10
            for card in range(1,11):
                name = 'cards/{}_{}.{}'.format(str(card),suit,'png')
                image = tkinter.PhotoImage(file = name)
                card_images.append((card,image))
            #next the Face Cards
            for card in face_cards:
                name = 'cards/{}_{}.{}'.format(str(card),suit,'png')
                image = tkinter.PhotoImage(file = name)
                card_images.append((10,image))
    
    def deal_card(frame):
        #pop the next card of the top of the deck
        next_card= deck.pop(0)
        #add the image to the label and display the label
        tkinter.Label(frame,image=next_card[1],relief = 'raised').pack(side = 'left')
        #now return the cards face value
        return next_card
    
    def deal_dealer():
        dealer_score= score_hand(dealer_hand)
        while 0 < dealer_score <17:
            dealer_hand.append(deal_card(dealer_card_frame))
            dealer_score= score_hand(dealer_hand)
            dealer_score_label.set(dealer_score)
    
        player_score = score_hand(player_hand)
        if player_score>21:
            resulttext.set('Dealer Wins!')
        elif dealer_score > 21 or dealer_score player_score:
            resulttext.set('Dealer Wins!')
        else:
            resulttext.set('Draw!')
    
        # player_score_label.set(player_score)
        # if player_score>21:
        #     resulttext.set ('Dealer Wins')
    
    
    # def deal_player():
    #     deal_card(player_card_frame)
    
    def deal_player():
        player_hand.append(deal_card(player_card_frame))
        player_score= score_hand(player_hand)
    
        player_score_label.set(player_score)
        if player_score>21:
            resulttext.set ('Dealer Wins')
        #below code is used for testing the global,local shadowing concept 
        # global player_score
        # global player_ace
        # card_value = deal_card(player_card_frame)[0]
        # if card_value ==1 and not player_ace:
        #     player_ace = True
        #     card_value = 11
        # player_score = player_score + card_value
        # # if we would bust,check if there is an ace and subtract
        # if player_score>21 and player_ace:
        #     player_score = player_score - 10
        #     player_ace = False
        # player_score_label.set(player_score)
        # if player_score>21:
        #     resulttext.set("Dealer Wins")
        # print(locals())
    
    def score_hand(hand):
        #calculate the total score of all cards in the list
        # only one can have the value 11,and this will be reduce to 1 if the hand would bust.
        score = 0
        ace = False
        for next_card in hand:
            card_value = next_card[0]
            if card_value == 1 and not ace:
                ace = True
                card_value = 11
            score = score + card_value
            #if we would bust ,check if there is an ace and subtract 10
            if score > 21 and ace:
                score =score - 10
                ace = False
            return score
    
    
    mainwindow = tkinter.Tk()
    
    #setup the screens and frame for the dealer and the player
    mainwindow.title("blackjack")
    mainwindow.geometry("640x480")
    mainwindow.configure(background = "green")
    
    resulttext = tkinter.StringVar()
    result = tkinter.Label(mainwindow,textvariable = resulttext)
    result.grid(row=0,column=0,columnspan=3)
    
    card_frame= tkinter.Frame(mainwindow,relief = 'sunken',borderwidth = 1,background = 'green')
    card_frame.grid(row=1,column=0,sticky = 'ew',columnspan = 3,rowspan=2)
    
    dealer_score_label = tkinter.IntVar()
    tkinter.Label(card_frame,text = 'Dealer',background ='green',fg='white').grid(row=0,column=0)
    tkinter.Label(card_frame,textvariable = dealer_score_label,background ='green',fg='white').grid(row=1,column=0)
    
    #embedded Frame hold the card images
    dealer_card_frame=tkinter.Frame(card_frame,background = 'green')
    dealer_card_frame.grid(row=0,column=1,sticky='ew',rowspan=2)
    
    
    player_score_label = tkinter.IntVar()
    tkinter.Label(card_frame,text = 'Player',background ='green',fg='white').grid(row=2,column=0)
    tkinter.Label(card_frame,textvariable = player_score_label,background ='green',fg='white').grid(row=3,column=0)
    #embedded Frame hold the card images
    player_card_frame=tkinter.Frame(card_frame,background = 'green')
    player_card_frame.grid(row=2,column=1,sticky='ew',rowspan=2)
    
    button_frame = tkinter.Frame(mainwindow)
    button_frame.grid(row=3,column=0,columnspan = 3,sticky = 'w')
    
    dealer_button=tkinter.Button(button_frame,text = 'Dealer',command = deal_dealer)
    dealer_button.grid(row=0,column=0)
    
    player_button=tkinter.Button(button_frame,text = 'Player',command = deal_player)
    player_button.grid(row=0,column=1)
    
    #load cards
    cards = []
    load_images(cards)
    # print(cards)
    # print(id(cards))
    #create a new deck of cards and shuffle them
    deck = list(cards)
    random.shuffle(deck)
    
    #Create the list to store the dealers and players hands
    dealer_hand = []
    player_hand = []
    
    deal_player()
    dealer_hand.append(deal_card(dealer_card_frame))
    deal_player()
    
    mainwindow.mainloop()