In-class notes for 04/23/2014 (CS 121B (CS1), Spring 2014)
Home
>>     < >




In-class notes for 04/23/2014

CS 121B (CS1), Spring 2014

Project ideas

Submitted questions on assignments and technology

  • Simulation with Stock class (Simulation problem 1b)

    • Define the class Stock

          class Stock:
              """Represents a company's stock for trading
                 State variable
                   price - float, current trading price for a stock"""
              
              def __init__(self, initPrice):
                  self.price = initPrice
          
              def getPrice(self):
                  return self.price
          
              def getNewPrice(self, val):
                  newPrice = 2*self.price*val
                  self.price = newPrice
                  return newPrice
          
      

    • Original code (using mere float values for stock prices)

      import random
      
      def main():
          
          stocks = [30, 50, 70, 90, 100]
          print("Initial stock values are", stocks)
      
          # invar:  stocks holds current stock prices after all changes so far
          for i in range(20):
              index = random.randrange(5)
              prev = stocks[index]
              stocks[index] = 2*prev*random.random()
              print("Stock {:d} changed from ${:.2f} to ${:.2f}".format(
                      index, prev, stocks[index]))
          
          print("Final stock values are", stocks)
      
      main()
      
    • Now, replace uses of the float by constructors/methods from the class Stock:

      • Replace list of floats

                stocks = [30, 50, 70, 90, 100]
        
        by list of constructor calls
                stocks = [Stock(30), Stock(50), Stock(70), Stock(90), Stock(100)]
        

      • Replace computation

                    stocks[index] = 2*prev*random.random()
        
        by method call
                    stocks[index].getNewPrice(random.random())
        

      • Replace float price lookup

            stocks[index]
        
        by method call
            stocks[index].getPrice()
        

      Resulting code:
      import random
      
      class Stock:
          ...
      
      def main():
          
          stocks = [Stock(30), Stock(50), Stock(70), Stock(90), Stock(100)]
          print("Initial stock values are", stocks)
      
          # invar:  stocks holds current stock prices after all changes so far
          for i in range(20):
              index = random.randrange(5)
              prev = stocks[index].getPrice()
              stocks[index].getNewPrice(random.random())
              print("Stock {:d} changed from ${:.2f} to ${:.2f}".format(
                      index, prev, stocks[index].getPrice()))
          
          print("Final stock values are", stocks)
      
      main()
      
    • One more adjustment: The two calls

              print("Initial stock values are", stocks)
          
              print("Final stock values are", stocks)
      
      will print a list of five values such as
           <Stock object at 0x7f36e8bb2ed0>
      
      instead of something useful, such as the value of the state variable price. To fix this, either

      • write a loop to print s.getPrice() for each stock s in the list stocks, as suggested in the problem, or

      • (better) implement a custom __str__() method in Stocks

                    def __str__(self):
                        return "{:.2f}".format(self.price)
        
        With this custom __str__() method, the call
                print("Final stock values are", stocks)
        
        will print something like
            Final stock values are [2.14, 50.00, 34.85, 0.06, 7.45]
        
        automatically calling that method __str__() for each Stock element in that list.

        This is better than the original float simulation, which would have printed

            Final stock values are [2.1386050068068556, 50, 34.850822519416795, 0.061276507691597, 7.44801595147697]
        

  • WMR concordance problem (Review)

    • Spec:

      Mapper

      # IN keys and values:
      #   key: holds lines of text from the corpus   value: is empty
      # OUT keys and values:
      #   key: one word from that corpus   value: the entire line containing that word
      

      Reducer

      # IN keys and values:
      #   key: one word from a corpus   value: an entire line containing that word
      # OUT keys and values:  
      #   key: that same word from that corpus  value: that same line of context
      

    • Sample input for mapper

          The cat in the hat
          wore the hat
          to the cat hat party.
      
    • Mapper code, working from the IN/OUT spec

          # IN keys and values:
          #   key: holds lines of text from the corpus   value: is empty
          # OUT keys and values:
          #   key: one word from that corpus   value: the entire line containing that word
          
          def mapper(key, value):
              lis = key.split()
              for word in lis:
      	    Wmr.emit(word, key)
      
      Note: You can always start the mapper() definition with the boldface line above.

    • Reducer code

          # IN keys and values:
          #   key: one word from a corpus   value: an entire line containing that word
          # OUT keys and values:  
          #   key: that same word from that corpus  value: that same line of context
          
          def reducer(key, iter):
              for val in iter:
      	    Wmr.emit(key, val)
      
      Note: You can always start the reduce() definition with the boldface line above.

    • A trace of the WMR computation:

      input
      =mapper IN
      the cat in the hat
      
      mapper()
      def mapper(key, value):
          lis = key.split()
          for word in lis:
              Wmr.emit(word, key)
      
      For first input line:
      key'the cat in the hat'
      value''
      lis['the', 'cat', 'in', 'the', 'hat']
      word'the'  'cat'  'in'  'the'  'hat'
      mapper OUT
      the	the cat in the hat
      cat	the cat in the hat
      in	the cat in the hat
      the	the cat in the hat
      hat	the cat in the hat
      
      Shuffle
      reducer IN
      cat	the cat in the hat
      hat	the cat in the hat
      in	the cat in the hat
      the	the cat in the hat
      the	the cat in the hat
      
      reducer()
      def reducer(key, iter):
          for val in iter:
              Wmr.emit(key, val)
      
      For call reducer('the', ...):
      key'the'
      iter'the cat in the hat'
      'the cat in the hat'
      val 'the cat in the hat'  'the cat in the hat'
      reducer OUT
      cat	the cat in the hat
      hat	the cat in the hat
      in	the cat in the hat
      the	the cat in the hat
      the	the cat in the hat
      

      Note: This reducer is an identity reducer -- copies key-value pairs to the very same key-value pairs

  • Comments on WMR problem 5a

Upcoming

Instances, class variables

  • OOP terminology: object, class, state variable, method, constructor

    An instance of a class is an object of that type. E.g., in the Account example, a1 and a2 are instances of Account.

  • Some state variables should be per class instead of per object. Examples: a bank name state variable; account ID numbers.

    A class variable is a state variable that is a single memory location shared by all objects (instead of each object having it's own memory location. (Memory diagram)

    The ordinary state variable per object are called instance variables.

  • Example of specifying a class variable.

  • Implementation: Account2.py

    • Define and initialize the class variable nextId within the class definition.

    • Refer to the class variable nextId as Account2.nextId within method definitions.

      (Otherwise, Python3 would think you mean an instance variable by that name nextId.)

    • In the constructor, define the new state variable id from Account2.nextId, then update Account2.nextId (so it will be ready for the next constructor call.)

    • Trace of Account2 sample calls

Exercise

  • Exercise 1:

    Define a Plant2 class that includes a id state variable and a nextId class variable, satisfying this class spec.

Remember: class variables are also considered to be state variables. Instance variable vs. class variable

__str__() method

  • Python3 makes it convenient to create a printable version of an object, which is useful for debugging.

        acct = Account2(1000)
        acct.deposit(200)
        print(acct)
        Account 1, balance $1200.00 (initially $1000.00)
    

  • This is accomplished by defining a method __str__() with no arguments that returns a string.

    Spec in the case of Account2

  • This can be done for any object, not just Account2




< >