<week title="Exam Grades, Legos, XML">
<assignment  due="10/24">

Honors-section homework

<blockquote>
<p>
 You have to work on this problem set with your new partner. 
</p>
<p>
 You may use Intermediate Student Language (ISL) for this assignment. 
</p>

<p>
You must follow the design recipe and the guidelines when you develop
functions.  We suggest you use helper functions liberally to improve
the readability of your code. 
</p>
</blockquote>

<hr />

<h1>Exam Grades</h1>

<p>Your professors and TAs have been grading Exam 1.  We were each
assigned a pile of exams to grade and when we're done grading we turn
in a list of exam grades for each of the students in our pile. 
</p>

<p>Here is the data definition for exam grades and lists of exam grades:</p>

<blockquote>
<pre>
(<span class='keyw'>define-struct</span> examgrade (student points comment))
 <span class='com'>;; An ExamGrade is a (make-examgrade String Number String)</span>

 <span class='com'>;; A LOEG (list of exam grades) is one of:</span> 
 <span class='com'>;; - empty</span> 
 <span class='com'>;; - (cons ExamGrade LOEG)</span> 
</pre>
</blockquote>

<p> Each exam grade records the name of the student, the student's
points on the exam, and a comment from the grader.</p>

<p><b>Exercise 1</b>: 
Design a function, <code>merge-ordered</code>, that takes two lists of
exam grades as input.  Both input lists are ordered by the points
scored on the exam, from highest to lowest.  Your function should
combine the two lists into one list of exam grades that is also in
descending order by number of points. 
</p>

<p><b>Exercise 2</b>: Professor Ahmed has just been given two lists
of exam grades for the students in the honors section.  The first list
contains students' grades for the regular exam, while the second
contains grades for the honors supplement.  She wants you to design a
function, <code>honors-totals</code>, that takes these two lists as
input and produces a list of exam grades that contains an entry for
each student with the student's total number of points (regular exam +
honors supplement).  Both input lists are alphabetically sorted by
student name and the output list should also be alphabetically sorted.
The two input lists, however, may not be of the same length (we 
sometimes misplace exams!).  We may
have a regular-exam grade for a student but no honors-supplement
grade, or vice versa.  In such cases, that student's entry in the
output list should have the points for whichever grade is available
(regular exam or honors supplement), together with the comment
<code>"Missing regular"</code> or <code>"Missing honors"</code>, as
appropriate.  Finally, all comments in the input lists should be
dropped.    
</p>

<p>Here are some examples (but you should develop more of your own):</p>

<blockquote>
<pre>
(honors-totals 
  (list (make-examgrade "Amal Ahmed" 58 "Aced it!") 
        (make-examgrade "Olin Shivers" 30 "Not so good"))
  (list (make-examgrade "Amal Ahmed" 44 "Wow!") 
        (make-examgrade "Olin Shivers" 25 "")))
--->
(list (make-examgrade "Amal Ahmed" 102 "") 
      (make-examgrade "Olin Shivers" 55 ""))

(honors-totals
  (list (make-examgrade "Amal Ahmed" 58 "Aced it!") 
        (make-examgrade "Olin Shivers" 30 "Not so good"))
  (list (make-examgrade "Leena Razzaq" 38 "")
        (make-examgrade "Olin Shivers" 25 "")))
--->
(list (make-examgrade "Amal Ahmed" 58 "Missing honors") 
      (make-examgrade "Leena Razzaq" 38 "Missing regular")
      (make-examgrade "Olin Shivers" 55 ""))
</pre>
</blockquote>

<hr />


<h1>Legos!</h1>

<p>Here are data definitions for lego bricks and lego buildings:</p>

<blockquote>
<pre>
(<span class='keyw'>define-struct</span> lego (label color width))
 <span class='com'>;; A Lego is a (make-lego Number Symbol Number)</span>

(<span class='keyw'>define-struct</span> bigger (lego left right))
 <span class='com'>;; A LegoBldg (lego building) is one of: </span>
 <span class='com'>;; - Lego</span> 
 <span class='com'>;; - (make-bigger Lego LegoBldg LegoBldg)</span> 
</pre>
</blockquote>

<p> Each lego brick has a label, color, and width (in
pixels).  We construct a lego building out of lego bricks, and make
bigger buildings by putting a lego brick on top of two lego buildings
(left and right). </p> 

<p><b>Exercise 3</b>: 
Design a function, <code>count-bricks</code>, that takes a lego
building and produces the total number of lego bricks in the
building. 
</p>

<p><b>Exercise 4</b>: 
Each lego brick is 10 pixels tall.  
Design a function, <code>how-high</code>, that takes a lego building
and produces the total height of the lego building (in pixels).  
</p>

<p><b>Exercise 5</b>: 
Design a function, <code>contains-colored-brick?</code>, that takes a
lego building and a color, and determines whether the building
contains a lego brick of the given color. 
</p>

<p><b>Exercise 6</b>: 
Design a function, <code>find-colored-brick?</code>, that takes a lego
building and a color and finds any lego with the given color in the
building, or returns false if there are no such legos.  
</p>

<p>
Here is a data definition for the type of data this function returns: 
</p>

<blockquote>
<pre>
 <span class='com'>;; A MaybeLego is one of:</span> 
 <span class='com'>;; - false</span> 
 <span class='com'>;; - Lego</span> 
</pre>
</blockquote>

<p>
Your function should not use <code>contains-colored-brick?</code>, it 
should not traverse/examine parts of the building more than once, and it
should stop searching once any brick of the given color is found.
</p>

<p><b>Exercise 7</b>: 
Design a function, <code>lego->image</code>, that takes a lego and
produces an image of the lego.  All legos are rectangular and 10
pixels tall.    
</p>

<p>Design a function, <code>lb->image</code>, that takes a lego
building and produces an image of the building.  (You may want to look
up <code>above</code> and <code>beside/align</code> in Help Desk.)
</p>

<p>
Here are some examples: 
</p>

<blockquote>
<pre>
(make-bigger (make-lego 4 'purple 80)
             (make-bigger (make-lego 2 'blue 60)
                          (make-lego 1 'yellow 40) 
                          (make-lego 3 'red 40))
             (make-bigger (make-lego 6 'orange 60)
                          (make-lego 5 'green 40) 
                          (make-lego 7 'red 40)))   

</pre>
<img src="legobldg.png" /> 
</blockquote>

<blockquote>
<pre>
(make-bigger (make-lego 4 'purple 80)
             (make-bigger (make-lego 2 'blue 60)
                          (make-lego 1 'yellow 40) 
                          (make-lego 3 'red 40))
             (make-lego 6 'orange 60))
</pre>
<img src="legobldg-asym.png" /> 
</blockquote>



<p><b>Exercise 8</b>: 
Design a function, <code>merge-lb</code>, that takes two lego
buildings and merges them into a new lego building.  Two buildings can
be merged if corresponding bricks (starting with the brick at the
top) are of the same color.  If the buildings cannot be merged, the
function should produce an error: <code>merge-lb: Colors don't
match</code>.  The two buildings need not have the same number of
bricks; the bricks in each building that don't correspond to bricks in
the other building should be discarded.  
</p>

<p>
Here's how two legos <code>la</code> and <code>lb</code> are
merged (assuming their colors match): 
<ul>
<li>If <code>la</code> is labeled with the number <code>m</code> and
<code>lb</code> is labeled with the number <code>n</code>, then the
lego we get by merging them is labeled with the number
<code>m.n</code>. 
</li>
<li>
The legos <code>la</code>, <code>lb</code>, and the merged lego piece
all have the same color. 
</li>
<li>
The widths of <code>la</code> and <code>lb</code> are added together to
get the width of the merged piece. 
</li>
</ul>
</p>

<p>Here are some examples to illustrate:</p>

<blockquote>
<pre>
(merge-lb 
  (make-bigger (make-lego 2 'blue 60)
               (make-lego 1 'yellow 40) 
               (make-lego 3 'red 40))
  (make-bigger (make-lego 2 'blue 60)
               (make-lego 1 'yellow 40) 
               (make-lego 11 'red 20)))
--->
(make-bigger (make-lego 2.2 'blue 120)
             (make-lego 1.1 'yellow 80) 
             (make-lego 3.11 'red 60))


(merge-lb
  (make-bigger (make-lego 4 'purple 80) 
               (make-bigger (make-lego 2 'blue 60)
                            (make-lego 1 'yellow 40) 
                            (make-lego 3 'red 40))                
               (make-lego 6 'orange 60))
  (make-bigger (make-lego 4 'purple 80) 
               (make-lego 2 'blue 60)
               (make-bigger (make-lego 6 'orange 60)
                            (make-lego 5 'green 40) 
                            (make-lego 7 'red 40))))                
--->
(make-bigger (make-lego 4.4 'purple 160)
             (make-lego 2.2 'blue 120)
             (make-lego 6.6 'orange 120)))
</pre>
</blockquote>
 
<hr />


<h1>Orderly Legos</h1>

Let's build a different kind of lego building where all legos
in the building must have distinct labels and brick labels
appear in a certain order in the building.  

<p>Here is the data definition for our ordered lego buildings:</p>

<blockquote>
<pre>
 <span class='com'>;; An OrdLegoBldg (ordered lego building) is one of:</span> 
 <span class='com'>;; - 'none</span> 
 <span class='com'>;; - Lego</span> 
 <span class='com'>;; - (make-bigger Lego LegoBldg LegoBldg)</span> 
 <span class='com'>;; where each lego brick in the building has a unique label and</span> 
 <span class='com'>;; where each (make-bigger l lft rgt) has the property that</span>  
 <span class='com'>;;  -- the label of l is bigger than all the labels in lft</span> 
 <span class='com'>;;  -- the label of l is smaller than all the labels in rgt</span> 
</pre>
</blockquote>

<p>
All functions that you design below must exploit/maintain the
distinct-label and label-ordering properties of
<code>OrdLegoBldg</code>s. 
</p>

<p><b>Exercise 9</b>: 
Design a function, <code>ord-lb-contains?</code>, that takes an
ordered lego building and a label and determines whether the building
contains a lego with that label. 
</p>

<p><b>Exercise 10</b>: 
Design a function, <code>colors-in-order</code>, that takes an
ordered lego building and produces a list of colors.  The output list
must be ordered so that it starts with the color of the lego with the
smallest label in the building and ends with the color of the lego
with the highest label.  
</p>

<p>
You may use <code>append</code> to concatenate lists of colors.  The
function should not traverse/examine parts of the building more than once. 
</p>

<p><b>Exercise 11</b>: 
Design a function, <code>grow-ord-lb</code>, that takes an
ordered lego building and a lego brick and adds the brick to the
building.  If the new brick's label is the same as the label of a
brick already in the building, return an error: <code>Label already in
building</code>.  The new building must be an <code>OrdLegoBldg</code>, that is, it
must respect the distinct-label and label-ordering properties of
<code>OrdLegoBldg</code>.   
</p>

<p><b>Exercise 12</b>: 
Design a function, <code>build-ord-lb</code>, that takes a list of
legos and produces an ordered lego building built using these legos.
The building must be an <code>OrdLegoBldg</code> (i.e., it must
satisfy the distinct-label and label-ordering properties of
<code>OrdLegoBldg</code>.).  If the input list contains multiple legos
with the same label, report an error.
</p>

<hr />


<h1>X-Expressions</h1>

<p>Here is the data definition for X-expressions:</p>

<blockquote>
<pre>
<span class='mcom'>#| X-expressions:

   Xexpr is one of: 
   -- (cons Symbol (cons LOA Xbody))
   -- (cons Symbol Xbody)

   Xbody is one of: 
   -- empty
   -- (cons String Xbody)
   -- (cons Xexpr Xbody)

   LOA is one of: 
   -- empty 
   -- (cons (list Symbol String) LOA)

   Note: (list Symbol String) is called an Attribute. 
   Furthermore, (list 'a "some text") is called an a-Attribute 
   and "some text" is its value. 
|#</span>
</pre>
</blockquote>

<p>X-expressions are used to represent XML information within the BSL
language</p>

<p>
The "teachpack" <a href="more-io.ss">more-io.ss</a> provides the
function read-xexpr for reading an entire XML files as an
X-expression.  To use the teachpack, save it in the same directory as
your code for the problem set.  In DrRacket, select the Language &gt;
"<i>Add Teachpack...</i>" menu item, then "<i>Add Teachpack to
List...</i>", then navigate to the location of <code>more-io.ss</code>
and add it.
</p>
<p style="color: red;">
Before submitting, any use of <code>read-xexpr</code> <em>must</em> be
commented out.
</p>

<p>Here is a sample XML piece:</p>

<pre>
	&lt;week&gt;
	 &lt;assignment&gt;
	  hello
	  &lt;syllabus week="2" src="sample2.xml" /&gt;
	  &lt;syllabus week="1" src="sample1.xml"&gt;
	   world
	  &lt;/syllabus&gt;
	 &lt;/assignment&gt;
	 done
	&lt;/week&gt;
</pre>

<p>
<b>Exercise 13</b>: Represent it as an X-expression to practice your data representation skills.
</p>

<p><b>Exercise 14</b>:
Your task is to design four functions: 
</p>

<ol>
  <li>
    <code>find-srcs</code>, which consumes the name of an XML file (a
    file whose extension is .xml and whose content is an XML
    expression) and produces the list of all the
    values of src attributes in the file.
  </li>

  <li>
    <code>xexpr-find</code>, which consumes an X-expression and
    produces the list of all the values of src attributes.
  </li>
  
  <li>
    <code>file-depth</code>, which determines the depth, also called
    complexity, of the XML in the file of the given name.

    <p>
      If you have at most one start tag per line and if you indent one
      more space every time you use an open tag without closing
      preceding tags, the depth of a piece of XML is the maximal number
      of spaces between a tag and the left border.
    </p>    
  </li>

  <li>
    <code>xexpr-depth</code>, which consumes an X-expression and
    determines its depth.
  </li>
</ol>

<p>
You should notice that two of the functions are one-line definitions,
if you use function composition to define them.

For your entertainment, this assignment comes with the XML file
<a href="6h.xml">6h.xml</a>, which stores information about this
assignment. You may use it to run your program (not test). For
testing, you must create a simpler file than this.
</p>


<p>
<b>Exercise 15</b>: The last problem required the design of the
functions: <code>xexpr-find</code>
and <code>xexpr-depth</code>. Because the description of the input
requires three data definitions, those of you who designed the
functions according to the design recipe came up with three mutually
interconnected functions (plus perhaps some auxiliary functions).
</p>

<p>
The first step to editing such clusters of
functions after they have been properly designed and corrected is to
re-organize them into a single function, just like the problem
statement (or your boss's request) states for both of the two
functions in this problem. Do so.
</p>

<p>
The reason for organizing code in this manner is to create an
organizational structure for future
readers. If <code>xexpr-find</code> or <code>xexpr-depth</code> occur
in the context of a large module or program that some reader wishes to
understand, he may just read the purpose statement and ignore the
internal nest of local functions during a first pass. This provides a
first overview of the module and puts everything in context. After
that, the reader can "drill" down wherever needed.
</p>

<p>
<b>Exercise 16</b>: XML experts refer to (the interpretation of) an Xexpr as an
element. Design the function <code>xexpr-elements</code>, which
consumes an X-expression <code>x</code> and symbol <code>t</code> and
extracts a list of all elements whose tag is <code>t</code>. Note that
an element with tag <code>t</code> may occur nested inside of some
other element with the same tag.
</p>

<p>
<b>Exercise 17</b>: Abstract
over <code>xexpr-find</code>, <code>xexpr-depth</code>, and
<code>xexpr-elements</code>. That is, create a single function that
consumes and processes an Xexpr and demonstrate that the three
functions are simple "instances" of this function.
</p>

<p>
Hint: Start from the template for all three functions. (Remember that
since all three functions process the same kind of input data their
templates---i.e., their organizational skeletons---are identical. Then
create a function that consumes appropriate "combinators" and "base
values" for the various clauses that must be distinct.
</p>

<p>
Knowledge: This abstraction is at the core of many XML processing
languages and thus shows up at the heart of many XML libraries.
</p>


</assignment>
</week>
