"""
This scripts stores a dictionary with the most important terminology
we encountered in the course.  The keys in the dictionary are the
lectures in which the terms were explained.
"""
TERMS = \
{ \
  '1.0':['computer science', 'algorithm', 'pseudocode', 'flowchart'] ,
  '1.5':['hardware', 'software', 'processor', 'memory', 'storage', \
         'volatile', 'persistent', 'peripherals', 'system bus', \
         'editor', 'compiler', 'interpreter', 'linker', 'debugger', 'IDE', \
         'assembler', 'machine code'] , \
  '2.0':['system clock', 'byte', 'ASCII', 'Unicode', 'CPU', 'ALU', \
         'control unit', 'register', 'RAM', 'ROM', 'cache', 'hard drive'] ,
  '2.5':['memory allocation', 'garbage collection', 'dynamic typing', \
         'floating-point number', 'machine precision', 'precision', \
         'accuracy', 'specification', 'implementation'] , \
  '3.0':['OS', 'PC', 'workstation', 'mainframe', 'virtual machine', \
         'shell', 'kernel of OS', 'interrupt', 'pagination' , \
         'segmentation', 'virtual memory', 'swap space', \
         'directory', 'UNIX', 'Linux', 'Cygwin', 'portable code' ], \
  '3.5':['language generation', 'syntax', 'semantics', 'BNF' ] , \
  '4.0':['mass storage', 'sequential access', 'direct access' , \
         'kilobyte', 'megabyte', 'gigabyte', 'terabyte', \
         'kilohertz', 'megahertz', 'gigahertz', 'terahertz', \
         'disk sector', 'cylinder on disk', 'latency time', 'seek time' , \
         'hash function', 'rule based programming' ], \
  '4.5':['logical expression', 'truth table'], \
  '5.0':['transistor', 'electronic circuit', 'logic gate'], \
  '5.5':['flip flop', 'latch', 'FIFO', 'FILO', 'queue', 'stack'], \
  '6.0':['bitwise operator'], \
  '6.5':['Monte Carlo method'], \
  '7.0':['top down design'], \
  '7.5':['call by value', 'call by reference', 'functional programming'], \
  '8.0':['trapdoor function'], \
  '8.5':['binary file', 'soft link', 'bottom up design'], \
  '9.0':['data compression', 'lossless data compression', \
         'lossy data compression', 'dictionary encoding compression'], \
  '9.5':['IP address', 'WAN', 'LAN', 'URL', 'TCP/IP', 'HTTP', 'XML', \
          'HTML', 'CGI'],  \
  '12.0':['modular design', 'information hiding', \
          'low coupling and high cohesion', 'design for change'], \
  '12.5':['software quality criteria', 'waterfall model' , \
          'spiral model'], \
  '13.0':['GNU', 'GPL', 'IPR', 'copyright', 'copyleft', 'open source'], \
  '13.5':['OOP', 'UML', 'class diagram', 'use case diagram'], \
  '14.0':['object-oriented programming', 'procedure-oriented programming', \
          'flop'], \
  '14.5':['procedure-oriented language', 'object-oriented language', \
          'framework language', 'encapsulation', 'polymorphism', \
          'wrapping', 'inheritance', 'method overriding'], \
  '15.0':['software bug', 'white-box testing', 'black-box testing', \
          'static testing', 'dynamic testing', 'verification', \
          'validation', 'beta testing', 'test to pass', 'test to fail', \
          'unit testing', 'integration testing', 'programming by contract', \
          'precondition', 'postcondition', 'loop invariant'], \
  '15.5':['robust', 'exception', 'raise exception', 'handle exception', \
          'anytime algorithm' ], \
  '16.0':['complexity', 'cost', 'complexity class', 'P complexity class', \
          'NP complexity class', '#P complexity class' ], \
  '16.5':['GUI', 'event driven interface', 'command line interface'], \
  '17.0':['callback function'], \
  '17.5':['RGB'], \
  '18.0':['multiple inheritance'], \
  '18.5':['cellular automaton'], \
  '19.0':['time sharing', 'process', 'thread', 'thread safe', \
          'critical section', 'lock', 'semaphore', 'deadlock'],  \
  '20.0':['bps', 'star network', 'ring network', 'bus network', \
          'client/server architecture', 'application layer', \
          'transport layer', 'network layer', 'link layer', 'TCP', 'UDP', \
          'socket', 'localhost'], \
  '20.5':['fork a process', 'speedup', 'quality up'], \
  '21.0':['generator', 'recursive algorithm', 'iterative algorithm'], \
}

def choose_term(nbr):
    """
    Generates a number in range(nbr)
    and returns the lecture key string
    and a term from the list as a tuple.
    """
    from random import choice
    trm = choice(range(nbr))
    kys = TERMS.keys()
    cnt = 0
    for key in kys:
        lgt = len(TERMS[key])
        cnt = cnt + lgt
        if cnt > trm:
            qst = choice(range(lgt))
            return (key, TERMS[key][qst])

def main():
    """
    Generates a random number from the range
    of the total number of terms.
    """
    keys = TERMS.keys()
    numb = sum([len(TERMS[k]) for k in keys])
    print 'We have', numb, 'terms to choose from ...'
    (lec, term) = choose_term(numb)
    print 'Explain the term : \"%s\".' % term
    print 'Hint: see lecture %s.' % lec

if __name__ == "__main__":
    main()
