WEEK08: more top-down design
---------------------------------------------------------------
 M: another TDD example

QUESTION from last week: 

 * how would you read in and store all the data in the itunes.csv
   file to be able to process it later and do something like this
   (sort it based on one field)?

$ python itunes-advanced.py 
--------------------------------------------------
         Do You Feel by                   The Rocket Summer -- 155 plays
             Tamacun by                  Rodrigo y Gabriela -- 149 plays
             It's On by                          Superchick -- 140 plays
  How Far We've Come by                     Matchbox Twenty -- 129 plays
     Big Yellow Taxi by    Counting Crows & Vanessa Carlton -- 119 plays
        Shining Star by                  Earth| Wind & Fire -- 117 plays
      Let's Get Loud by                   Countdown Singers -- 113 plays
--------------------------------------------------

 * could use parallel lists, one for each field:

songnames = []
artists = []
times = []
genres = []
purchasedate = []
plays = []
albums = []

 * could use a list to hold each song info:

song1 = ["Lights","Ellie Goulding","3:32:00","Pop","4/9/2012 15:15:00",1,"Lights",2011]

   and then have another list to hold all of the song lists:

songdb = [[song1 list], [song2 list], ... [last song list]]

   This is the list-of-lists approach. 

 * could write our own Song() class, then store a list of song objects!

song1 = Song("Lights","Ellie Goulding","3:32:00","Pop",...,2011)
songdb = [song1, song2, song3, .... ]

  * How would we get the ith song's number of plays for each
    of these data structures??

   parallel lists: plays[i]
    list-of-lists: songdb[i][5]       # NOTE: songdb[i] is just the ith list in the list-of-lists
list of Song objs: songdb[i].getPlays()   # NOTE: getPlays() would be a method we write for the Song() class!


ANOTHER TOP-DOWN DESIGN: tic-tac-toe game

 - want main() written out
 - decide on your data structure
 - assume each function will work
 - think about data going to/from each function
 - write out function stubs
 - get main() and function stubs working (no syntax errors!)
 - once your design is done, start implementing each function
   one-at-a-time (debug and test as you go)

 * pseudo-code for tic-tac-toe game:

 initialize empty board
 draw board
 loop:
   ask user to choose
   update/draw new board
   check if game over
   computer turn
   update/draw new board
   check if game over

 * what data structure can we use???
   python list??? or list of lists???

board = [' ', 'x', ' ', ' ', 'x', 'o', ' ', 'o', 'x']

 - has 9 items, first 3 correspond to top row, etc
 - store single char: ' ' for empty space, etc
 - here's how it might be drawn to terminal screen:

 |x| 
-----
 |x|o
-----
 |o|x

 * now let's write the main() function:

def main():
  """run one game of tic-tac-toe"""

  board = [" "]*9
  display(board)
  while True:
    userturn(board)
    result = checkIfGameOver(board)
    if result != None:
      break
    computerTurn(board)
    result = checkIfGameOver(board)
    if result != None:
      break

  if result == "x":
    print "X wins!"
  elif result == "o":
    print "O wins!"
  else:
    print "it's a draw...."

 * and each function stub:

def display(b):
  """display tic-tac-toe board to terminal window"""

  print 
  print b
  print 

# ----------------------------------------------------- #

def userturn(board):
  """get user's selection, update and display board"""

  # need to add loop, make sure valid input
  i = int(raw_input("user turn: "))
  board[i] = "x"
  display(board)
  return

# ----------------------------------------------------- #

def checkIfGameOver(board):
  """
  check if someone has won, or a draw.
  return "x" if X wins, "o" if O wins, "d" if draw, 
         None if game not over
  """

  return None

# ----------------------------------------------------- #

def computerTurn(board):
  """find best spot and play it"""

  board[4] = "o"
  display(board)
  return

 * they don't all do everything they need to, yet, but it should RUN!