Lab4


Lab 4: Blocks and Ordered Collections


The first part of this lab will be an intro to blocks, and the second part will be on collections. At the end, you will use your new-found knowledge in both areas to do something cool.

What is a block?

A block is a sequence of statements enclosed in square brackets. It can be passed to other statements as an argument. A block may have parameters too. Refer to page 516-517 of Coad/Nicola book.

What am I going to do?

First, create a subclass of OrderedCollection, and call it MyList. This class has only three instance methods:

        initialize
                1 to: 15 do: [:i | self add: i]

doBlock: aBlock aBlock value: self.

eachDo: aBlock 1 to: self size do: [:index | self at: index put: ( aBlock value: (self at: index))]

Then, in the Workspace, write:

        |temp list sum result|

list := MyList new initialize. sum := [:aList | temp := 0. aList do:[:v | temp := temp + v]. result := temp. ].

list doBlock: sum. Transcript show: result printString; cr.

Here, sum is a block. It takes a collection as parameter, and get the sum of the value of that collection. After the execution of the above, you should get 120 as result.

Now add one more variable inc1 in the variable list. And append the code below in the workspace.

        inc1 := [:each | each + 1].
        Transcript show: list printString; cr.
        list eachDo: inc1.
        Transcript show: list printString; cr.

The block inc1 is used to increase one element of the collection by one. After ``do it'', you should get two MyList's displayed, and the second one should have all it's elements increased by one.

Now, here comes your job. You should make the following blocks:

average
Similar to sum, but get the average value as result.

deviation
It gets the squared deviation from average as the result. The deviation from average of a collection is defined as

        (   (x1 - average)2
                + (x2 - average)2
                + ...
                + (xn - average)2 ) / (n - 1)
(note the square operations) As an example, the standard deviation of (1 to: 5) should be 2.5.

squ
It sets the value of each element of the collection to the square of itself.

Then, your Workspace should looks like:

        |temp list sum result inc1 average deviation squ|

list := MyList new initialize. sum := [:aList | temp := 0. aList do:[:v | temp := temp + v]. result := temp. ].

list doBlock: sum. Transcript show: result printString; cr.

average := []. "<-- Your job"

list doBlock: average.

Transcript show: result printString; cr.

deviation := []. "<-- Your job"

list doBlock: deviation.

Transcript show: result printString; cr.

inc1 := [:each | each + 1].

list eachDo: inc1.

list doBlock: sum.

Transcript show: result printString; cr.

list doBlock: average.

Transcript show: result printString; cr.

list doBlock: deviation.

Transcript show: result printString; cr.

squ := []. "<-- Your job"

list eachDo: squ.

list doBlock: sum.

Transcript show: result printString; cr.

list doBlock: average.

Transcript show: result printString; cr.

list doBlock: deviation.

Transcript show: result printString; cr.

Turn In

Turn in: a copy of the workspace with your blocks for average, deviation, etc., as described above. (Don't forget to use CrLfFileStream.cs!)

The below information may help you in doing this lab


The Collection Class and Friends...

Simply put a Collection represents a group of objects. The objects that a Collection is comprised of are called elements. A Collection is any grouping you can think of. You have probably encountered Arrays in CS 1502.

The following is a crude partial representation of the Collection hierarchy (done in ASCII so you folks using lynx won't be left out. The level of indentation indicates subclasses.).

         Collection
                   SequenceableCollection
                             LinkedList
                             ArrayedCollection
                                       Array
                             OrderedCollection
                                       SortedCollection
                   Bag
                   Set
                             Dictionary

Let's try and put the System Browser through it's paces. Open a System Browser and search for the Collection class ( middle mouse menu find class... in the Class Categories pane). Select one of the Collection class Categories, and then select some of the protocols and methods and browse the comments. From what you read, can you figure out what the collection classes do? Click on some of the other classes in that category. Then look at the comments on the classes in the Collections-Unordered category.

This lab is going cover the following collections

The figure on the next page provides a road map for finding the collection class most appropriate for a given situation.

The Class Protocol

All Collections support four method categories for accessing elements:

A single or group of elements can be added or removed from a collection. It is also possible to test whether a collection is empty or whether it includes a particular element. Enumeration allow access to the elements without removing them from the collection.

Essentially, the following should work on all Collections:

       adding
                   add: newObject
                             Include the argument, newObject , as one of the receiver's
                             elements. Answer newObject.
                   addAll: aCollection
                             Include all the elements of the argument, aCollection,
                             as the receiver's elements. Answer aCollection.
       removing
                   remove: oldObject
                             Remove the argument, oldObject, from the receiver's
                             elements. Answer oldObject unless now element is equal
                             to oldObject, in which case report that an error occurred.
                   removeAll: aCollection
                             opposite of addAll.
       testing
                   includes: anObject
                             Answer whether the argument, anObject, is equal to one
                             of the receivers elements.
                   isEmpty
                             Answer whether the receiver contains any elements.
                   occurencesOf: anObject
                             Answer how many of the receiver's elements are equal to
                             the argument. anObject.
       enumerating
                   do: aBlock
                             Evaluate the argument, aBlock, for each of the receiver's
                             elements.
                   select: aBlock
                             Evaluate the arguments, aBlock, for each of the receiver's
                             elements. Collect into a new collection like that of the
                             receiver, only those elements for which aBlock evaluates
                             to true. Answer the new collection.
                   collect: aBlock
                             Evaluate the argument, aBlock, for each the receiver's
                             elements. Answer a new collection like that of the
                             receiver containing the values returned by the block on
                             each evaluation.

Some Basic Collections

Open a new Workspace window and relabel it Fun with Collections. In that window enter the following:

                             MySet:= Set new.
                             MySet add: 'a'.
                             MySet add: 2390.
                             MySet add: ( Set new )

Highlight the whole thing and then choose do it. Declare MySet as a global when asked. Then highlight MySet and choose inspect. Peruse around inside of the set for a while. Then select the MySet add: 2390 line and print it. What should have happened? Check the tally to see if you where right.

Now let's try out a Bag. Enter the following:

                             MyBag := Bag new.
                             MyBag add: 'a'.
                             MyBag add: 2390.
                             MyBag add: ( Set new )

Do the same sequence of operations as you did for Set. Should you get the same results?

When Order Matters

Now, let's try out an Ordered Collection. [ For the purposes of the this example let's make all the elements the instances of the same class. They don't have to be.]

                             MyOrdered := OrderedCollection new.
                             MyOrdered add: 'Swimming'.
                             MyOrdered add: 'Baseball'.
                             MyOrdered add: 'Track&Field'.
                             MyOrdered add: 'Gymnastics'

Again, do it, inspect MyOrdered and observe. Next try the following. In what order will the elements be in?

                             MySorted := SortedCollection new.
                             MySorted add: 'Swimming'.
                             MySorted add: 'Baseball'.
                             MySorted add: 'Track&Field'.
                             MySorted add: 'Gymnastics'

Conversions

try the following

                             MyBag asOrderedCollection

Highlight this and choose print it. Try this out too.

                             MySorted asSet

Try a few others. Converting the MySet or MyBag to a SortedCollection will result in an error. There are limits to the preinstalled magic.

Dictionaries

Sometimes it is useful, convenient, and/or efficient to look data up by a key.

                             MyTable := Dictionary new.
                             MyTable at: 12345 put: MySorted.
                             MyTable at: 12 put: MyOrdered ; at: 505 put: MyBag

You should now the routine by now... Close the inspector window and then invoke do it on the following.

                             MyTable at: MyOrdered put: MySorted

Objects can serve as keys. After all numbers are objects too. Reinspect MyTable. You can add to dictionaries this way too.

                             MyTable add: (Association key: #aKey value: #aValue )

Enumeration on a Collection

Often you want to do something with all the elements with a collection. In Pascal you might have created a for loop and iterated through an array. In Smalltalk, methods that iterates over a Collection are provided for you.

Basically these methods take a Block as an argument. The elements are assigned to the local variable defined in the block and the code is executed. For example, enter the following in the Fun with Collections window and then do it.

                   Transcript show: 'The MySet elements: ' ; cr.
                   MySet do: [:anObj | Transcript show: (anObj printString ) ; cr ].
                   Transcript cr ; show: 'The MyBag elements: ' ; cr.
                   MyBag do: [ :anObj | Transcript show: ( anObj printString ); cr ]

In the above code, each block is applied to each element in the Collection. You can also collect and select elements out of a collection. These operations result in new collections. Highlight each line below separately and choose print it.

                   MySorted select: [ :anObj| anObj = 'Baseball' ]
                   MyOrdered collect: [ :anObj | anObj = 'Baseball' ]
                   MySorted  collect: [ :anObj | anObj = 'Baseball' ]

For the first, if the block is true then that element is put a new collection of the same type. For the second, the result of the block is used as the new element in the collection of the same type being created. Note however that the Sorted returned a Ordered. Collecting things in the corresponding order takes precedence ( or there is no collect method for SortedCollections... probably the latter.).


News Page | CS2390 Win'98 Home Page | CS2390 CoWeb | STABLE | BOOST
Questions/comments/concerns to guzdial@cc.gatech.edu
Page last updated 2/3/98; 4:39:43 PM