title: Automate the Boring Stuff - Chapter 5 - Chess Dictionary Validator
body: <p>First post, new to programming and having fun! All feedback on this post and my questions are welcome.</p>
  
  <p>I'm working through Automate the Boring Stuff and attacking the first Chapter 5 problem <a href="https://automatetheboringstuff.com/2e/chapter5/" rel="nofollow noreferrer">Chess Dictionary Validator</a>.</p>
  
  <p><em>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.</em></p>
  
  <p><em>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.</em></p>
  
  <p><strong>my questions and code:</strong></p>
  
  <ol>
  <li>Is evaluating dictionary keys/values through these for loops + multiple if statements the "best practice"? It seems like a lot of code. Changing to include some elif caused issues if it followed with another if statement in the for loop.</li>
  <li>Line 23 <code>if i[0] == 'b':</code> errors out because the chess spaces which are empty string values have no character at i[0]. What's the best way to express/evaluate empty values? If it is with '', should I add leading condition in the loop which evaluates value == '', and then 'continue'?</li>
  <li>Why can I not collapse line 15 into 11 such that I have one statement: <code>if 'bking' or 'wking' not in board.values():</code>? If I try that, the statement result is True; however the dictionary contains both values so shouldn't it evaluate to False and keep the code running?</li>
  </ol>
  
  <pre><code>def isValidChessBoard(board):
      while True:
          blackPieces = 0
          whitePieces = 0
          wpawn = 0
          bpawn = 0
          letterAxis = ('a','b','c','d','e','f','g','h')
          pieceColour = ('b','w')
          pieceType = ('pawn','knight','bishop','rook','queen','king')
  
          #one black king and one white king
          if 'bking' not in board.values():
              print('KingError')
              return False
              break
          if 'wking' not in board.values():
              print('KingError')
              return False
              break
  
          #each player has &lt;= 16 pieces
          for i in board.values():
              if i[0] == 'b':
                  blackPieces+=1
              if i[0] == 'w':
                  whitePieces+=1
              if whitePieces &gt;= 17:
                  print('TotalPieceError')
                  return False
                  break
              if blackPieces &gt;= 17:
                  print('TotalPieceError')
                  return False
                  break
  
          #each player has &lt;= 8 pawns
          for i in board.values():
              if i == 'wpawn':
                  wpawn+=1
              elif i == 'bpawn':
                  bpawn+=1
              if wpawn or bpawn &gt;= 9:
                  print('PawnError')
                  return False
                  break
  
          #all pieces must be on valid space from '1a' to '8h'
          for i in board.keys():
              if int(i[0]) &gt;= 9:
                  print('SpacesError')
                  return False
                  break
              if i[1] not in letterAxis:
                  print('yAxisError')
                  return False
                  break
  
          #piece names begin with 'w' or 'b'
          for i in board.values():
              if i[0] not in pieceColour:
                  print('WhiteOrBlackError')
                  return False
                  break
  
          #piece names must follow with 'pawn', 'knight', 'bishop', 'rook', 'queen', 'king'
          for i in board.values():
              if i[1:] not in pieceType:
                  print('PieceTypeError')
                  return False
          return 'This board checks out'
  
  board = {'1a': 'bking','2a': 'bqueen','3a': 'brook','4a': 'brook',
  '5a': 'bknight','6a': 'bknight','7a':'bbishop','8a': 'bbishop',
  '1b': 'bpawn','2b': 'bpawn','3b': 'bpawn','4b':'bpawn',
  '5b': 'bpawn','6b': 'bpawn','7b': 'bpawn','8b': 'bpawn',
  '1c': 'wking','2c': 'wqueen','3c': 'wrook','4c': 'wrook',
  '5c': 'wbishop','6c': 'wbishop','7c': 'wknight','8c':'wknight',
  '1e': 'wpawn','2e': 'wpawn','3e': 'wpawn','4e': 'wpawn',
  '5e': 'wpawn','6e': 'wpawn','7e': 'wpawn','8e': 'wpawn',
  '1f': '','2f': '','3f': '','4f': '','5f': '','6f': '','7f': '','8f': '',
  '1g': '','2g': '','3g': '','4g': '','5g': '','6g': '','7g': '','8g': '',
  '1h': '','2h': '','3h': '','4h': '','5h': '','6h': '','7h': '','8h': '',}
  
  print(isValidChessBoard(board))
  
  Error:
  Traceback (most recent call last):
  line 23, in isValidChessBoard
      if i[0] == 'b':
  IndexError: string index out of range
  </code></pre>