beginner – Chess Dictionary Validator from Automatic Boring Stuff with Python

This project is in chapter 5 introduced me to a whole new world of dictionary data structure. To put it briefly, I want to know whether the choice I took between lists, tuples, and dictionaries could’ve been justifiable calls or not. I’m also not that confident about where putting many return statements correctly and many other beginners’ common mistakes that I probably have overlooked.

The project’s description and the code are shown below.

import pprint, copy

# Argument from Automate BS with Python
chessgood = {
'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop', '5h': 'bqueen', '3e': 'wking'}

# Argument when key/value is ok but its representative value/key pair raises an error
chessbad = {'9z': 'bemperor', '10a': 'wking', '3a': 'bprince'}

# Argument when a piece is more than allowed (e.g., wpawn more than 8)
chessbad2 = {'4a': 'wpawn', '4b': 'wpawn', '4c': 'wpawn','4d': 'wpawn',
'4e': 'wpawn', '4f': 'wpawn', '4g': 'wpawn', '4h': 'wpawn', '5a': 'wpawn',
'5i': 'wpawn'}


def isvcb(dctnry):
    '''
    In this chapter, we used the dictionary value {'1h': 'bking', '6c': 'wqueen',
    '2g': 'bbishop', '5h': 'bqueen', '3e': 'wking'} to represent a chess board.
    Write a function named isValidChessBoard() that takes a dictionary argument
    and returns True or False depending on if the board is valid.
    A valid board will have exactly one black king and exactly one white
    king. Each player can only have at most 16 pieces, at most 8 pawns, and
    all pieces must be on a valid space from '1a' to '8h'; that is, a piece can’t
    be on space '9z'. The piece names begin with either a 'w' or 'b' to represent
    white or black, followed by 'pawn', 'knight', 'bishop', 'rook', 'queen', or
    'king'. This function should detect when a bug has resulted in an improper
    chess board.
    '''

    ver = ('a','b','c','d','e','f','g','h')
    hor = (8, 7, 6, 5, 4, 3, 2, 1)
    bd = dict()
    for i in hor:
        for j in ver:
            bd.setdefault(str(i) + j, str(i) + j)
    bdcopy = copy.copy(bd)
    #pprint.pprint(bdu)

    side = ('b','w')
    piece = {'pawn': 8, 'knight': 2, 'bishop': 2, 'rook': 2, 'queen' : 1, 'king': 1}
    pcs = dict()
    for m in side:
        for n in piece:
            pcs.setdefault(m + n, piece(n))

    temp = dict()
    for k,v in dctnry.items():
        temp.setdefault(v, 0)
        temp(v) += 1

        if k in bd and v in pcs and temp(v) <= pcs(v):
            bd(k) = v
            print('Input OK: ', k)

        elif k not in bd:
            bd = bdcopy
            print('Key(s) not in definition: ', k )

        elif v not in pcs:
            bd = bdcopy
            print('Value(s) not in definition: ', v )

        elif temp(v) > pcs(v):
            bd = bdcopy
            print('Value of this piece exceeds threshold: ', v )

    pprint.pprint(bd)
    

    if bd == bdcopy:
        return False
    else:
        return True

print('chessgood: ', isvcb(chessgood),  'n')
print('chessbad: ', isvcb(chessbad), ' n')
print('chessbad2: ', isvcb(chessbad2), 'n')

I believe I covered all of the possible errors by error-checking using different arguments when calling the function, where:

  1. Key of the passed arguments are not on the matrix 1a – 8h
  2. Value of the passed arguments are outside from a combination of (white & black) and (‘pawn’, ‘knight’, ‘bishop’, ‘rook’, ‘queen’, ‘king’)
  3. All of the value from passed arguments don’t exceed the threshold of each piece so that each piece will have aat most 16 pieces (e.g. wpawn is notmore than 8, bking is no more than 1)
  4. Show all the invalid input on the command line

If there are any other subtle restrictions that I haven’t overseen. Please let me know πŸ™‚

The results are shown below:

Input OK:  1h
Input OK:  6c
Input OK:  2g
Input OK:  5h
Input OK:  3e
{'1a': '1a',
 '1b': '1b',
 '1c': '1c',
 '1d': '1d',
 '1e': '1e',
 '1f': '1f',
 '1g': '1g',
 '1h': 'bking',
 '2a': '2a',
 '2b': '2b',
 '2c': '2c',
 '2d': '2d',
 '2e': '2e',
 '2f': '2f',
 '2g': 'bbishop',
 '2h': '2h',
 '3a': '3a',
 '3b': '3b',
 '3c': '3c',
 '3d': '3d',
 '3e': 'wking',
 '3f': '3f',
 '3g': '3g',
 '3h': '3h',
 '4a': '4a',
 '4b': '4b',
 '4c': '4c',
 '4d': '4d',
 '4e': '4e',
 '4f': '4f',
 '4g': '4g',
 '4h': '4h',
 '5a': '5a',
 '5b': '5b',
 '5c': '5c',
 '5d': '5d',
 '5e': '5e',
 '5f': '5f',
 '5g': '5g',
 '5h': 'bqueen',
 '6a': '6a',
 '6b': '6b',
 '6c': 'wqueen',
 '6d': '6d',
 '6e': '6e',
 '6f': '6f',
 '6g': '6g',
 '6h': '6h',
 '7a': '7a',
 '7b': '7b',
 '7c': '7c',
 '7d': '7d',
 '7e': '7e',
 '7f': '7f',
 '7g': '7g',
 '7h': '7h',
 '8a': '8a',
 '8b': '8b',
 '8c': '8c',
 '8d': '8d',
 '8e': '8e',
 '8f': '8f',
 '8g': '8g',
 '8h': '8h'}
chessgood:  True

Key(s) not in definition:  9z
Key(s) not in definition:  10a
Value(s) not in definition:  bprince
{'1a': '1a',
 '1b': '1b',
 '1c': '1c',
 '1d': '1d',
 '1e': '1e',
 '1f': '1f',
 '1g': '1g',
 '1h': '1h',
 '2a': '2a',
 '2b': '2b',
 '2c': '2c',
 '2d': '2d',
 '2e': '2e',
 '2f': '2f',
 '2g': '2g',
 '2h': '2h',
 '3a': '3a',
 '3b': '3b',
 '3c': '3c',
 '3d': '3d',
 '3e': '3e',
 '3f': '3f',
 '3g': '3g',
 '3h': '3h',
 '4a': '4a',
 '4b': '4b',
 '4c': '4c',
 '4d': '4d',
 '4e': '4e',
 '4f': '4f',
 '4g': '4g',
 '4h': '4h',
 '5a': '5a',
 '5b': '5b',
 '5c': '5c',
 '5d': '5d',
 '5e': '5e',
 '5f': '5f',
 '5g': '5g',
 '5h': '5h',
 '6a': '6a',
 '6b': '6b',
 '6c': '6c',
 '6d': '6d',
 '6e': '6e',
 '6f': '6f',
 '6g': '6g',
 '6h': '6h',
 '7a': '7a',
 '7b': '7b',
 '7c': '7c',
 '7d': '7d',
 '7e': '7e',
 '7f': '7f',
 '7g': '7g',
 '7h': '7h',
 '8a': '8a',
 '8b': '8b',
 '8c': '8c',
 '8d': '8d',
 '8e': '8e',
 '8f': '8f',
 '8g': '8g',
 '8h': '8h'}
chessbad:  False

Input OK:  4a
Input OK:  4b
Input OK:  4c
Input OK:  4d
Input OK:  4e
Input OK:  4f
Input OK:  4g
Input OK:  4h
Value of this piece exceeds threshold:  wpawn
Key(s) not in definition:  5i
{'1a': '1a',
 '1b': '1b',
 '1c': '1c',
 '1d': '1d',
 '1e': '1e',
 '1f': '1f',
 '1g': '1g',
 '1h': '1h',
 '2a': '2a',
 '2b': '2b',
 '2c': '2c',
 '2d': '2d',
 '2e': '2e',
 '2f': '2f',
 '2g': '2g',
 '2h': '2h',
 '3a': '3a',
 '3b': '3b',
 '3c': '3c',
 '3d': '3d',
 '3e': '3e',
 '3f': '3f',
 '3g': '3g',
 '3h': '3h',
 '4a': '4a',
 '4b': '4b',
 '4c': '4c',
 '4d': '4d',
 '4e': '4e',
 '4f': '4f',
 '4g': '4g',
 '4h': '4h',
 '5a': '5a',
 '5b': '5b',
 '5c': '5c',
 '5d': '5d',
 '5e': '5e',
 '5f': '5f',
 '5g': '5g',
 '5h': '5h',
 '6a': '6a',
 '6b': '6b',
 '6c': '6c',
 '6d': '6d',
 '6e': '6e',
 '6f': '6f',
 '6g': '6g',
 '6h': '6h',
 '7a': '7a',
 '7b': '7b',
 '7c': '7c',
 '7d': '7d',
 '7e': '7e',
 '7f': '7f',
 '7g': '7g',
 '7h': '7h',
 '8a': '8a',
 '8b': '8b',
 '8c': '8c',
 '8d': '8d',
 '8e': '8e',
 '8f': '8f',
 '8g': '8g',
 '8h': '8h'}
chessbad2:  False

I believe my code is way longer than necessary but I also believe that the result being true should be kept as the first priority. So as someone who has no background in coding. Any input is greatly appreciated. Thank you πŸ™‚