# Lab 10: Scheme Data Abstraction lab10.zip

Due by 11:59pm on Tuesday, August 2.

## Starter Files

Download lab10.zip. Inside the archive, you will find starter files for the questions in this lab, along with a copy of the Ok autograder.

# Topics

Consult this section if you need a refresher on the material for this lab. It's okay to skip directly to the questions and refer back here should you get stuck.

## Data Abstractions

Data abstraction is a powerful concept in computer science that allows programmers to treat code as objects. For example, using code to represent cars, chairs, people, and so on. That way, programmers don't have to worry about how code is implemented; they just have to know what it does.

Data abstraction mimics how we think about the world. If you want to drive a car, you don't need to know how the engine was built or what kind of material the tires are made of to do so. You just have to know how to use the car for driving itself, such as how to turn the wheel or press the gas pedal.

A data abstraction consists of two types of functions:

• Constructors: functions that build the abstract data type.
• Selectors: functions that retrieve information from the data type.

Programmers design data abstractions to abstract away how information is stored and calculated such that the end user does not need to know how constructors and selectors are implemented. The nature of abstraction allows whoever uses them to assume that the functions have been written correctly and work as described. Using this idea, developers are able to use a variety of powerful libraries for tasks such as data processing, security, visualization, and more without needing to write the code themselves!

In Python, you primarily worked with data abstractions using Object Oriented Programming, which used Python `Object`s to store the data. Notably, this is not possible in Scheme, which is a functional programming language. Instead, we create and return new structures which represent the current state of the data.

## Example Data Abstractions

### `Rational`

Recall that a rational number is any number that can be expressed as p / q, where p and q are integers.

``````; Creates the rational number n/d (Assume n, d are integers and d != 0)
; Note that the constructor simplifies the numerator and denominator.
(rational n d)

; Gets the numerator of rational number r
(numer r)

; Gets the denominator of rational number r
(denom r)

; Adds two rational numbers x and y

; Multiplies two rational numbers x and y
(mul-rational x y)``````

### `Trees`

Below is a Scheme-ified data abstraction of the Tree class we've been working with this semester.

``````; Constructs tree given label and list of branches
(tree label branches)

; Returns the label of the tree
(label t)

; Returns the list of branches of the given tree
(branches t)

; Returns #t if t is a leaf, #f otherwise
(is-leaf t)``````

# Required Questions

## What Would Scheme Do?

### Q1: WWSD: Data Abstractions

Let's familiarize ourselves with some Scheme data abstractions!

If you need a refresher on the `tree` and `rational` abstractions, refer to this lab's introduction or Wednesday 07/27's lecture.

Use Ok to test your knowledge with the following "What Would Python Display?" questions:

``python3 ok -q abstractions -u``

``````scm> (load rational.scm)
scm> (define x (rational 2 5))

scm> (numer x)

scm> (denom x)

scm> (define y (rational 1 4))

scm> (define z1 (add-rational x y))

scm> (numer z1)

scm> (denom z1)

scm> (define z2 (mul-rational x y)) ; don't forget to reduce the rational!

scm> (numer z2)

scm> (denom z2)``````
``````scm> (load tree.scm)
scm> (define t (tree 1 (list (tree 2 nil)) ))

scm> (label t)

scm> (length (branches t))

scm> (define child (car (branches t)))

scm> (label child)

scm> (is-leaf child)``````
``````scm> (load tree.scm)
scm> (define b1 (tree 5 (list (tree 6 nil) (tree 7 nil)) ))

scm> (map is-leaf (branches b1))    ; draw the tree if you get stuck!

scm> (define b2 (tree 8 (list (tree 9 (list (tree 10 nil)) )) ))

scm> (map is-leaf (branches b2))    ; draw the tree if you get stuck!

scm> (define t (tree 11 (list b1 b2)))

scm> (label t)

scm> (map (lambda (b) (label b)) (branches t)) ; draw the tree if you get stuck!``````

## Code Writing Questions

Remember that when working with data abstractions, you should not break the abstraction barrier if possible! Later questions will have abstraction checks, where the underlying representation of the abstraction will be changed; thus, attempting to refer to specifics of the implementation will break. Attempt to use the functions you are creating to interface with the classes whenever possible.

### Teachers and Students

In the following questions, you'll be implementing data abstractions for students and teachers:

1. The `teacher` abstraction keeps track of the teacher's `name`, the `class` they teach, and the `students` enrolled in their class. Specifically, a `teacher`'s `name` and `class` are atomic symbols, and their `students` is a list of `student` objects.
2. The `student` abstraction keeps track of a student's `name` and the `classes` they have attended. Specifically, a `student`'s `name` is an atomic symbol, and their `classes` is a list of atomic symbols representing all classes attended. For example, if a student had attended `cs61a` and `astronomy`, their `classes` list would be `(cs61a astronomy)`.

You can find the constructors for these classes below:

``````(define (student-create name classes) (cons name classes))
(define (teacher-create name class students) (cons name (cons class students)))``````

### Q2: Teachers and Students: Selectors

Implement `student-get-name`, `student-get-classes`, `teacher-get-name`, `teacher-get-class`, and `teacher-get-students`. These functions take in a `student` or `teacher` abstraction, and return the relevant attribute; for example, `student-get-name` takes a `student` as input, and returns the `name`.

``````(define (student-get-name student)
'YOUR-CODE-HERE
)

(define (student-get-classes student)
'YOUR-CODE-HERE
)

(define (teacher-get-name teacher)
'YOUR-CODE-HERE
)

(define (teacher-get-class teacher)
'YOUR-CODE-HERE
)

(define (teacher-get-students teacher)
'YOUR-CODE-HERE
)``````

Use Ok to test your code:

``python3 ok -q teacher_student_selectors``

### Q3: Students: Attend Class

Implement `student-attend-class`. This method takes in a `student` and a `class` as input, and returns a new `student` abstraction with the `class` list updated to reflect the `class` attended.

Be sure to keep the abstraction barrier in mind!

``````(define (student-attend-class student class)
'YOUR-CODE-HERE
)``````

Use Ok to test your code:

``python3 ok -q student_attend_class``

### Q4: Teachers: Hold Class

Implement `teacher-hold-class`. This method takes in a `teacher` as input, and emulates holding a class. Specifically, the function should return a new updated `teacher`, where all `student` objects in the `teacher`'s `students` list have updated `class` lists to reflect their attendance.

Be sure to keep the abstraction barrier in mind! Feel free to use any of the functions implemented in previous parts of this lab. You may also find the `map` function useful.

``````(define (teacher-hold-class teacher)
'YOUR-CODE-HERE
)``````

Use Ok to test your code:

``python3 ok -q teacher_hold_class``

## Submit

Make sure to submit this assignment by running:

``python3 ok --submit``