Background
See Beautiful Racket unit testing explainer and Lab 3 for how to create a test suite.
See the Beautiful Racket lists explainer and Section 2.3 of the Racket Guide for how to work with lists.
You can find more information on racket's XML utilities at docs.racket-lang.org
- Data Explorer
What to hand in, and how to hand it in
- Make a directory
~fcshome/cs2613/assignments/A2
(i.e. in your git repo for this class). All files related to this assigment should be saved in that directory. - Make sure you commit and push all your work using git before 16:30 on Friday October 7.
Marking
- This assignment will be worth 5% of your final grade.
- For a marking scheme, see racket-assignment
Getting Started
This assignment will use the XML of the rubrics exported from D2L. Download that file and commit it as
~fcshome/cs2613/assignments/A2/rubrics.xml
Racket provides functions to read XML into special S-expressions (lists) called X-expressions. Here is some code you can use to read an xml file into racket
(require xml)
(define (load-xexpr path)
(xml->xexpr (document-element (read-xml (open-input-file path)))))
- Your VMs have the Data Explorer installed, which you can think
of as a graphical, interactive replacement for
displayln
orprintf
. You will probably want to use it for several questions in this assignment.
(require explorer)
(define data (load-xexpr "rubrics.xml"))
(explore data)
What forms to use
Other than the given use of read-xml
, xml->expr
, and any use of
explore
for visualization, you should only use forms (functions and
macros) provided by #lang racket
(and those you write yourself).
Questions
Q1 Loading the rubrics
- Use
load-xexpr
and appropriate list manipulation to write a functionload-rubrics
which passes the following tests.
(module+ test
(require rackunit)
(define rubrics (load-rubrics "rubrics.xml"))
(check-equal? (length rubrics) 5)
(for ([elt rubrics])
(check-equal? (first elt) 'rubric)))
Q2 Improving assoc
Racket has a built in function assoc that is useful for doing searches of lists
> (assoc 3 (list (list 1 2) (list 3 4) (list 5 6)))
'(3 4)
> (assoc 9 (list (list 1 2) (list 3 4) (list 5 6)))
#f
For our XML parsing purposes we want to make two tweaks to how this
function works. First, we want to ignore top level elements that are
not lists. Second, we want to return just the value
part of the
sublist (key value)
. Use
match to write a
function assoc*
that passes the following tests (note the use of
assoc*
to extract the rubric name).
(module+ test
(define test-list '(1 [keep 2] 3 [keep 4] [keep 5] 6))
(check-equal? (assoc* 'keep test-list) 2)
(check-equal? (assoc* 'discard test-list) #f))
(define (rubric-name rubric)
(assoc* 'name (second rubric)))
(module+ test
(check-equal?
(sort (map rubric-name rubrics) string<=?)
'("JavaScript Assignment" "Journal Entry" "Octave Assignment" "Python Assignment"
"Racket assignment")))
Q3 Keep all the pairs
Another useful extension to assoc
is to have it return all the
matching pairs. Write a tail-recursive function assoc-all
that
passes the following tests.
(module+ test
(check-equal? (assoc-all 'keep test-list) '([keep 2] [keep 4] [keep 5])))
(define (criteria-groups rubric)
(assoc-all 'criteria_group
(assoc 'criteria_groups (rest rubric))))
(module+ test
;; Journals have one group, others have 2
(check-equal? (sort (map length (map criteria-groups rubrics)) <=)
'(1 2 2 2 2))
(check-equal?
(first ;; tag
(first ;; first criteria group
(criteria-groups (first rubrics))))
'criteria_group))
Q4 Extracting criteria levels
Use assoc-all
and other appropriate list functions to write
function criteria-levels
passing the following tests
(module+ test
(for ([level (criteria-levels (first (criteria-groups (first rubrics))))])
(check-equal? (first level) 'level)))
Q5 Reformatting level information
Write a function level-name-score
that extracts the level name and value, and passes the following test
(module+ test
(check-equal? (map level-name-score (criteria-levels (first (criteria-groups (first rubrics)))))
'(("Needs improvement" 0)
("Minimally satifactory" 1)
("Good" 2)
("Excellent" 3))))