Top Banner
COS 126 Class Meeting November 8th, 2019 Dr. Jérémie Lumbroso [email protected]
32

COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Jul 15, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

COS 126 Class Meeting

November 8th, 2019Dr. Jérémie Lumbroso

[email protected]

Page 2: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Agenda for today

1. Debrief on LFSR

2. Overview of Guitar Hero

3. RingBuffer

4. GuitarString

5. From GuitarHeroLite (provided) to GuitarHero

Page 3: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Live Questions on Sli.do• QUESTIONS ARE WELCOME

during this class meeting

• Go to https://sli.do

• Enter meeting code: #5904

• You can:

• ASK your own questions

• UPVOTE questions you are interested in hearing the answer of

• Will try to monitor and select questions

• Please be kind!

Page 4: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Debrief on LFSRWILL BE RELEASED THURSDAY EVENING

Page 5: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Some Statistics

~1/4 of students

~3/4 of students

- Some used String.substring

- Others had string concatenation

quadratic performance

WILL BE RELEASED THURSDAY EVENING

Page 6: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Style comments from LFSR1. Many students (at least 78) hard-coded certain constants,

such as 8 in lfsr.generate(8)

• Better instead to define a constant:private final static int NUM_BITS = 8;

• We will start deducting next week2. When an instance variable is only assigned once (either in

declaration or in constructor) and never again, we can use the Java keyword final to indicate this—and Java warn us if we accidentally change the value

3. Use Character.getNumericValue(x) or (x - '0') to get "numeric" value of character

Page 7: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Please provide feedback

• We are currently exploring new and more efficient ways to write better rubrics

• We really would appreciate feedback on:

• the quality of explanations

• the usefulness to your programming skill growth

Page 8: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Better testing in main()• In main(), you want to call all the methods you have

implemented, to make sure they do not crash

• But that is not enough!

• You should also "test" whether a sequence of operations produces the result you expect

LFSR lfsr2 = new LFSR("01101000010", 9);

assert(lfsr2.generate(5) !== 25); assert(lfsr2.generate(5) !== 4); assert(lfsr2.generate(5) !== 30); assert(lfsr2.generate(5) !== 27);

assert(<expression>) will raise an error if the <expression> evaluates to false; it will do nothing if <expression> evaluates to true

Page 9: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Tests should include expected result

• assert(<expression>) will raise an error if the <expression> evaluates to false; it will do nothing if <expression> evaluates to true

• Alternatively, you can print out the output you get AND the value you expect:

To enable assert in jshell, use jshell -R -ea

LFSR lfsr2 = new LFSR("01101000010", 9);

StdOut.println(lfsr2.generate(5) + " should be 25"); StdOut.println(lfsr2.generate(5) + " should be 4"); StdOut.println(lfsr2.generate(5) + " should be 30"); StdOut.println(lfsr2.generate(5) + " should be 27");

LFSR lfsr2 = new LFSR("01101000010", 9);

assert(lfsr2.generate(5) !== 25); assert(lfsr2.generate(5) !== 4); assert(lfsr2.generate(5) !== 30); assert(lfsr2.generate(5) !== 27);

Page 10: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Guitar Hero Overview

Page 11: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

What is the assignment • Simulate the vibration of a string,

and produce actual sound wave

• Create an actual digital instrument

• Deepen your understand of classes in Java

Page 12: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Overview• RingBuffer is your first classic data structure, a queue.

• Each GuitarString uses 1 RingBuffer.

• GuitarHero uses 37 GuitarStrings.

GuitarString RingBuffer

GuitarString RingBuffer

GuitarString RingBuffer

GuitarString RingBuffer

GuitarHero

(imagine 37strings)

Page 13: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

What You Need To Know• Further practice of OOP programming and how to

combine multiple classes together

• Introduction + application of one possible implementation of the abstract Queue data type

• Implement complex abstractions

• RingBuffer implements a "circular buffer" by using a modulo wrap-around

• Using first, last and size to maintain "state"

• Implement an event-loop for a real-time program

Page 14: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

You can now partner• You can work with a partner—in your

precept or another

• There is a partnering policy you should review

• Essentially both partners need to be present for any work on the code to take place

• Video-conferencing (and screen-sharing) is an acceptable substitute to in-person

• Create a group on TigerFile

• Pair programming is actually an industry practice

Page 15: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Reminder: Live Questions• QUESTIONS ARE WELCOME

during this class meeting

• Go to https://sli.do

• Enter meeting code: #5904

• You can:

• ASK your own questions

• UPVOTE questions you are interested in hearing the answer of

• Will try to monitor and select questions

• Please be kind!

Page 16: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

RingBuffer

Page 17: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

The Queue abstract data type

• A RingBuffer is a queue with a given capacity.

• A queue is a data structure that allows the user to store elements by calling enqueue() and returns them in the same order when the user calls dequeue().

• Queues are typically implemented with linked lists—which allows them to grow to any size. Both topics covered next week.

dequeue()

BACK FRONT

enqueue()

FIFO = First In First Out

Page 18: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

A RingBuffer Example

• Initially an double[] array is created to store the RingBuffer; the length of this array is also called capacity = 6

• All the values are 0.0

• first and last are set to 0

• size is set to 0

01

2

34

5

0 1 2 3 4 5

0.0

0.0

0.0

0.0

0.0

0.0

0.0 0.0 0.0 0.0 0.0 0.0

A) first

last

first

last

RingBuffer rb = new RingBuffer(6);

size = 0

What you will implement

What the "abstraction" is

capacity

Page 19: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

0 1

2

34

5

0 1 2 3 4 5

0.40

0.0

0.0

0.0

0.0

0.0

0.40 0.0 0.0 0.0 0.0 0.0

B) first

last

first

last

0 1

2

34

5

0 1 2 3 4 5

0.40

0.72

0.0

0.0

0.0

0.0

0.40 0.72 0.0 0.0 0.0 0.0

C) first

last

first

last

0 1

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.0

0.0

0.0

0.40 0.72 0.3 0.0 0.0 0.0

D) first

last

first

last

01

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.0

0.0

0.0

0.40 0.72 0.3 0.0 0.0 0.0

E)first

last

first

last

01

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.11

0.0

0.0

0.40 0.72 0.3 0.11 0.0 0.0

F)first

last

first

last

rb.enqueue(0.4) rb.enqueue(0.72) rb.enqueue(0.3)

rb.dequeue() !!--> 0.40

01

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.11

0.0

0.0

0.40 0.72 0.3 0.11 0.0 0.0

G)

firstlast

first

last

rb.dequeue() !!--> 0.72rb.enqueue(0.11)

size = 1 size = 2 size = 3

size = 2 size = 3 size = 2

Page 20: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

The peek() operation

• The peek() operation provides the same output that dequeue() would, but unlike dequeue() it does not change the RingBuffer

01

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.11

0.0

0.0

0.40 0.72 0.3 0.11 0.0 0.0

G)

firstlast

first

last

rb.dequeue() !!--> 0.3size = 2

0 1

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.11

0.0

0.0

0.40 0.72 0.3 0.11 0.0 0.0

H1)

firstlast

first

last

size = 2

0 1

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.11

0.0

0.0

0.40 0.72 0.3 0.11 0.0 0.0

H2)

first

last

first

last

size = 1

rb.peek() !!--> 0.3

peek()

dequeue()

Note: capacity = 6

Page 21: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

The wrap-around• Eventually, if we continue adding values, first and last will wrap

around the array

• Use modulo % and the capacity to do this

• Example below after adding 0.8, showing wrap around

0 1

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.11

0.8

0.0

0.40 0.72 0.3 0.11 0.8 0.0

first

last

first

last

size = 30 1

2

34

5

0 1 2 3 4 5

0.40

0.72

0.3

0.11

0.8

0.27

0.40 0.72 0.3 0.11 0.8 0.27

first

last

first

last

size = 4

Note: capacity = 6

rb.enqueue(0.27)rb.enqueue(0.8)H3) I)

Page 22: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

String representation of RingBuffer (optional but helpful)• Having a good string representation for toString() of your

RingBuffer might be helpful to debug.

• Typically try to display IV in a useful way

• What values are in the buffer?

• Where are first and last?

• Maybe even size and/or capacity?

first last ------------------------------------------------ | 0.40 !|| 0.72 !|| 0.30 !|| 0.11 !|| !|| | ------------------------------------------------ 0 1 2 3 4 5

Page 23: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

My string representation

in action

Page 24: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Pitfalls• The capacity never changes; it's the length of the underlying array

that is allocated in the constructor of RingBuffer

• Do not try to compute the size; just:

• Increment the size by 1 when you enqueue()

• Decrease the size by 1 when you dequeue()

• And make sure every time it is about to change that

• The size does not become negative

• The size does not grow beyond the capacity

• Remember that the array can be filled with "ghost" values (values that have been dequeued, but that have not yet been overwritten yet)

Page 25: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

GuitarString

Page 26: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

GuitarString

• GuitarString simulates the Karplus-Strong algorithm

• Produce initial "excitation" of the string

• Then simulate dampening as string oscillates (and produces sound)

• Different sizes of RingBuffer lead to different frequencies/notes

GuitarString RingBuffer

Page 27: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Two constructors• Two constructors: Both constructors must initialize all instance variables

•GuitarString(double frequency)

• "The first constructor creates a RingBuffer of the desired capacity n (the sampling rate 44,100 divided by the frequency, rounded up to the nearest integer), and initializes it to represent a guitar string at rest by enqueuing n zeros."

•GuitarString(double[] init)

• "The second constructor creates a RingBuffer of capacity equal to the length n of the array, and initializes the contents of the ring buffer to the corresponding values in the array. In this assignment, this constructor's main purpose is to facilitate testing and debugging."

Page 28: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Using RingBuffer

• How are you going to remove all items?

• How are you going to fill the RingBuffer with noise?

• How are you going to fill the RingBuffer with zeroes?

public class RingBuffer { public RingBuffer(int capacity) !// creates an empty ring buffer with the specified capacity public int capacity() !// returns the capacity of this ring buffer public int size() !// returns the number of items currently in this ring buffer public boolean isEmpty() !// is this ring buffer empty (size equals zero)? public boolean isFull() !// is this ring buffer full (size equals capacity)? public void enqueue(double x) !// adds item x to the end of this ring buffer public double dequeue() !// deletes and returns the item at the front of this ring buffer public double peek() !// returns the item at the front of this ring buffer

public static void main(String[] args) !// tests this class by directly calling all instance method }

Page 29: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

tic()

• tic() simulates another time step of the sound wave we are calculating by:

• calculating the average of the front two elements

• multiply by DECAY_FACTOR (= 0.996)

• adding the result to the RingBuffer

• removing the first element (but not the second)

• How can you look at the second value (here .4) without removing it from RingBuffer?

Page 30: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

From GuitarHeroLite to GuitarHero

Page 31: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

From 2 to many

create an array+ use for-loop to initialize at right frequency

use the keyboardStr.indexOf(s) trick(see checklist) not 37-way if-statement

use for-loop to sum sample from all strings

use for-loop to call tic() for all strings

Page 32: COS 126 Class Meeting...The Queue abstract data type • A RingBuffer is a queue with a given capacity. • A queue is a data structure that allows the user to store elements by calling

Questions?