Sale!

Assignment 3: JingleNet

$30.00

Category:
Rate this product

Assignment 3: JingleNet

> JingleNet has sprinkled a touch of magic into our communication at the North
> Pole, making it as smooth as freshly fallen snow. — Santa Claus

At the North Pole, Santa and his elves use the **JingleNet announcement system**
to play announcements over the North Pole loud speakers for all to hear.

Your task is to write a program named [a3.cpp](a3.cpp) that processes a sequence
of JingleNet commands, and outputs the resulting announcements in the proper
order.

For example, here are the JingleNet commands in
[jinglenet_input1.txt](jinglenet_input1.txt):

“`
SEND greenie elf2 send candy canes
ANNOUNCE 1
SEND yumyum elf2 I love candy canes!
ANNOUNCE 2
“`

`SEND` puts an announcement into the JingleNet queue system, and `ANNOUNCE n`
prints the next `n` announcements to `announcements.txt`. To run the program on
this input you would type:

“`
> ./a3 jinglenet_input1.txt
2 announcements written to announcements.txt
“`

And the contents of `announcements.txt` is:

“`
1: {greenie, elf2, “send candy canes”}
2: {yumyum, elf2, “I love candy canes!”}
“`

The details of all the commands and how they work are given below.

## JingleNet Architecture

The JingleNet system is essentially one large queue built from 5 internal
queues:

![JingleNet Architecture](JingleNetArchitecture.png)

When an announcement is added to JingleNet it is placed in the queue for its
**rank**. Every announcement has one of these 5 ranks:

– **santa**: the highest rank
– **reindeer**: the second highest rank
– **elf2**: the third highest rank
– **elf1**: the fourth highest rank
– **snowman**: the lowest rank

Ranks are per-announcement. There could be announcements from the same user in
different queues at the same time.

Here’s a textual representation of the queues when they are empty:

“`
(left is front of queue, right is back of queue)
santa: []
reindeer: []
elf2: []
elf1: []
snowman: []
“`

And here’s what they look like with a total of 5 announcements in the system:

“`
(left is front of queue, right is back of queue)
santa: [{yumyum, santa, “I love Christmas!”}, {lili, santa, “Hi!!”}]
reindeer: [{yumyum, reindeer, “mmm, peppermint”}]
elf2: []
elf1: []
snowman: [{choco, snowman, “choco4ever”}, {yumyum, snowman, “I’m hungry!”}]
“`

As noted, the left-most item is at the *front* of each queue, and the right-most
item is at the *back*. So items are enqueued at the right end and de-queued at
the left.

## JingleNet Commands

JingleNet is controlled by 4 commands:

– **SEND** *username* *rank* *message*: *username* sends an announcement of rank
*rank* with text *message*
– **REMOVE_ALL** *username*: all announcements from *username* are removed from
the JingleNet system
– **PROMOTE_ANNOUNCEMENTS** *username*: all announcements from *username* are
moved to the next highest rank
– **ANNOUNCE** *n*: the next *n* announcements are printed to
`announcements.txt`

The `Announcement` class is in [Announcement.h](Announcement.h). `Announcement`
objects are *immutable*, i.e. once created they cannot be changed. Here are
three different ways to create the same announcement (see
[announcement_demo.cpp](announcement_demo.cpp)):

“`c++
Announcement a1(“yumyum”, Rank::SANTA, “I love Christmas!”);
cout << a1 << endl; // prints: {yumyum, santa, “I love Christmas!”}

// copy another Announcement
Announcement a2(a1);
cout << a2 << endl; // prints: {yumyum, santa, “I love Christmas!”}

// parse a string of the form “sender_name rank text”
Announcement a3(“yumyum santa I love Christmas!”);
cout << a3 << endl; // prints: {yumyum, santa, “I love Christmas!”}
“`

### Sending Announcements

**SEND** *username* *rank* *message*

This adds an announcement from *username* of rank *rank* with text *message* to
the JingleNet system.

For example, suppose the JingleNet queues look like this:

“`
(left is front of queue, right is back of queue)
santa: [{yumyum, santa, “I love Christmas!”}, {lili, santa, “Hi!!”}]
reindeer: [{yumyum, reindeer, “mmm, peppermint”}]
elf2: []
elf1: []
snowman: [{choco, snowman, “choco4ever”}, {yumyum, snowman, “I’m hungry!”}]
“`

Then after this command:

“`
SEND yumyum Snowman yaaay!
“`

The queues look like this:

“`
(left is front of queue, right is back of queue)
santa: [{yumyum, santa, “I love Christmas!”}, {lili, santa, “Hi!!”}]
reindeer: [{yumyum, reindeer, “mmm, peppermint”}]
elf2: []
elf1: []
snowman: [{choco, snowman, “choco4ever”}, {yumyum, snowman, “I’m hungry!”},
{yumyum, snowman, “yaaay!”}]
“`

### Removing Announcements

**REMOVE_ALL** *username*

This removes all announcements from *username*, whatever queue(s) they are in.
If there are no announcements from *username*, then nothing happens.

For example, suppose the JingleNet queues look like this:

“`
(left is front of queue, right is back of queue)
santa: [{lili, santa, “Hi!!”}, {yumyum, santa, “I love Christmas!”}]
reindeer: []
elf2: []
elf1: []
snowman: [{yumyum, snowman, “yaaay!”}]
“`

Then after this command:

“`
REMOVE_ALL yumyum
“`

The queues look like this:

“`
(left is front of queue, right is back of queue)
santa: [{lili, santa, “Hi!!”}]
reindeer: []
elf2: []
elf1: []
snowman: []
“`

### Promoting Announcements

**PROMOTE_ANNOUNCEMENTS** *username*

This moves all announcements from *username* to the next highest queue.
Announcements are dequeued from their current queue and then enqueued in the
queue one rank higher. Nothing happens to announcements in the **santa** queue:
they are already at the highest rank.

When promoting announcements, start with **reindeer** queue and work downwards.
First any announcements in the **reindeer** are promoted to the **santa** queue,
and then any announcements in the **elf2** queue are promoted to the
**reindeer** queue, and so on.

When items are put into another queue, they are enqueued at the back in the
usual way. If multiple announcements are promoted from a queue, then they are
enqueued so they appear in the same order as in the queue they were promoted
from.

For example, suppose the queues look like this:

“`
(left is front of queue, right is back of queue)
santa: [{lili, santa, “Hi!!”}, {yumyum, santa, “I love Christmas!”}]
reindeer: [{yumyum, reindeer, “Rocking horse repair needed!”},
{rudolph, reindeer, “I’m hungry!”}]
elf2: []
elf1: []
snowman: [{yumyum, snowman, “yaaay!”}, {choco, snowman, “choco4ever”},
{yumyum, snowman, “I’m hungry”}]
“`

Then after the command:

“`
PROMOTE_ANNOUNCEMENTS yumyum
“`

The queues look like this:

“`
(left is front of queue, right is back of queue)
santa: [{lili, santa, “Hi!!”}, {yumyum, santa, “I love Christmas!”},
{yumyum, santa, “Rocking horse repair needed!”}]
reindeer: [{rudolph, reindeer, “I’m hungry!”}]
elf2: []
elf1: [{yumyum, elf1, “yaaay!”}, {yumyum, elf1, “I’m hungry”}]
snowman: [{choco, snowman, “choco4ever”}]
“`

### Announcing Announcements

**ANNOUNCE** *n*

De-queues and announces the next *n* announcements from the queues in this
order:

– All announcements in the **santa** queue, in the order they were enqueued.
– Then all announcements in the **reindeer** queue, in the order they were
enqueued.
– Then all announcements in the **elf2** queue, in the order they were enqueued.
– Then all announcements in the **elf1** queue, in the order they were enqueued.
– Then all announcements in the **snowman** queue, in the order they were
enqueued.

If there are fewer then *n* announcements in the queues, then all announcements
are removed (in the proper order). You can assume that *n* is always a positive
integer.

To announce a announcement, use `jnet.announce` from
[JingleNet_announcer.h](JingleNet_announcer.h):

“`
jnet.announce(a);  // a is an Announcement
“`

The announcements are automatically printed to the file `announcements.txt` when
the program ends. To use `jnet.announce` all you need to do is #include
[JingleNet_announcer.h](JingleNet_announcer.h) in your program.

> **Be careful!** `announcements.txt` gets over-written at the end of every
> program that uses [JingleNet_announcer.h](JingleNet_announcer.h).

Please be sure to announce announcements in this exact way using
`jnet.announce`.

Here’s an example of how announcing works. Suppose the queues look like this:

“`
(left is front of queue, right is back of queue)
santa: [{lili, santa, “Hi!!”}, {yumyum, santa, “I love Christmas!”}]
reindeer: [{yumyum, reindeer, “Rocking horse repair needed!”},
{yumyum, reindeer, “I’m hungry!”}]
elf1: [{yumyum, elf1, “yaaay!”}, {yumyum, elf1, “I’m hungry”}]
elf2: []
snowman: [{choco, snowman, “choco4ever”}]
“`

Then after this command:

“`
ANNOUNCE 3
“`

This removes the next 3 announcements from the queues. The queues then look like
this:

“`
(left is front of queue, right is back of queue)
santa: []
reindeer: [{yumyum, reindeer, “I’m hungry!”}]
elf1: [{yumyum, elf1, “yaaay!”}, {yumyum, elf1, “I’m hungry”}]
elf2: []
snowman: [{choco, snowman, “choco4ever”}]
“`

When the program ends, `announcements.txt` looks like this (assuming no other
announcements were made):

“`
1: {lili, santa, “Hi!!”}
2: {yumyum, santa, “I love Christmas!”}
3: {yumyum, reindeer, “Rocking horse repair needed!”}
“`

## Special Requirements

– Put all your code for this assignment into a single file called
[a3.cpp](a3.cpp). It should have a `main` function that reads the name of a
file and processes it like this:

“`
> ./a3 input1.txt

“`

See [getline_demo.cpp](getline_demo.cpp) for an example of reading
command-line arguments and processing a file line-by-line.

– Inside [a3.cpp](a3.cpp), implement your own queue class called `Queue` that
inherits from [Queue_base.h](Queue_base.h). Also:
– Your `Queue` does *not* need to be a template class, e.g. it can inherit
from `Queue_base<Announcement>`.
– For this assignment, you must implement your `Queue` using either a
singly-linked or doubly-linked list that you code yourself. Do **not** use
arrays, vectors, or other containers to implement `Queue`.
– Make sure that all methods meet the performance requirements listed in
[Queue_base.h](Queue_base.h).

– Implement a class called `JingleNet` that stores the 5 queues. The details of
this class are up to you. Implement it in a sensible way that makes your
program easy to understand. For instance, `JingleNet` could have a method for
each JingleNet command above.

## Sample Runs

Here are a few sample input files and their corresponding output files:

– [jinglenet_input1.txt](jinglenet_input1.txt), [output1.txt](output1.txt)
– [jinglenet_input2.txt](jinglenet_input2.txt), [output2.txt](output2.txt)
– [jinglenet_input3.txt](jinglenet_input3.txt), [output3.txt](output3.txt)
– [jinglenet_input4.txt](jinglenet_input4.txt), [output4.txt](output4.txt)
– [jinglenet_input5.txt](jinglenet_input5.txt), [output5.txt](output5.txt)

You can run them like this:

“`
❯ ./a3 jinglenet_input1.txt
2 announcements written to announcements.txt

❯ cat announcements.txt
1: {greenie, elf2, “send candy canes”}
2: {yumyum, elf2, “I love candy canes!”}
“`

The `diff` command is useful for comparing files:

“`
❯ ./a3 jinglenet_input1.txt
2 announcements written to announcements.txt

> diff announcements.txt output1.txt

“`

`diff` only prints differences between the files, so no output means the files
are the same.

## What to Submit

When you’re done, submit your finished [a3.cpp](a3.cpp) file on Canvas. Don’t
submit anything else.

## Grading

The marker will compile and run your program on Ubuntu Linux using
[makefile](makefile) like this:

“`bash
> make a3
g++ -std=c++17 -Wall -Wextra -Werror -Wfatal-errors -Wno-sign-compare -Wnon-virtual-dtor -g a3.cpp -o a3

> valgrind ./a3 some_input_file.txt
… testing output …
“`

Your program will be tested on a variety of inputs, including some you haven’t
seen before.

## Marking Scheme

### The Queue Class: 10 marks

– **1 mark**: [a3.cpp](a3.cpp) contains a class named `Queue` that inherits from
[Queue_base.h](Queue_base.h).
– **4 marks**: All the methods in `Queue` listed in [Queue_base.h](Queue_base.h)
work correctly.
– **2 marks**: All the methods in `Queue` meet the performance requirements
listed in [Queue_base.h](Queue_base.h).
– **3 marks** The `Queue` class is implemented using either a singly-linked or
doubly-linked list that you code yourself. Do **not** use arrays, vectors, or
other containers to implement `Queue`.

### The JingleNet Class: 4 marks

– **2 marks**: [a3.cpp](a3.cpp) contains a class named `JingleNet` that stores
the 5 queues.
– **2 marks**: The `JingleNet` class is used in a sensible way that makes your
program easier to understand.

### Correctness: 13 marks

– **5 marks**: valgrind reports no memory leaks or other errors when the program
runs.
– **5 marks**: The program produces the correct output for
[jinglenet_input1.txt](jinglenet_input1.txt),
[jinglenet_input2.txt](jinglenet_input2.txt),
[jinglenet_input3.txt](jinglenet_input3.txt),
[jinglenet_input4.txt](jinglenet_input4.txt), and
[jinglenet_input5.txt](jinglenet_input5.txt).
– **3 marks**: The program produces the correct output for another input file,
in the same style as the jinglenet_input files supplied by the markers.

### Overall source code readability: 5 marks

– All code is sensibly and consistently indented, and all lines are 100
characters in length, or less. **Hint**: In the Linux command-line you can
print all the lines in a file with more than 100 characters with this command
(the initial `>` is the prompt character, so don’t type it):

“`bash
> awk ‘length > 100’ some_file.cpp
“`

If this prints nothing, then the file has no lines over 100 characters long.

– Whitespace is used to group related pieces of a code to make it easier for
humans to read. All whitespace has a purpose.
– Variable and function names are self-descriptive.
– Appropriate features of C++ are used, as discussed in the course. **Note** If
you use a feature that we haven’t discussed in class, **you must explain it in
a comment**, even if you think it’s obvious.
– Comments are used when needed to explain code whose purpose is not obvious
from the code itself. There should be *no* commented-out code from previous
versions.
– Source code readability marks may be deducted for code that is unreadable in
some way not covered by the above. The deduction is proportional to how
serious the problem is.

### Deductions

– **-5 marks** if valgrind reports any memory leaks or other errors during the
markers test runs.
– **-5 marks** if your program crashes on any valid test.
– **a score of 0** if you:
– have no statement of originality, or it’s modified in any way.
– At least **-1 mark** if your file has an incorrect name, or you submit it in
an incorrect format, etc.; possibly multiple deductions if there are multiple
problems.
– At least **-1 mark** if you submit a non-working file.
– If the marker can easily fix your file and make it work, then there is only a
small deduction.
– If the marker has to spend a lot of time fixing your file, then there is a
larger deduction; if they can’t make it work, then they you will get 0.

There may be other deductions, depending upon the circumstances.

Reviews

There are no reviews yet.

Be the first to review “Assignment 3: JingleNet”

Your email address will not be published. Required fields are marked *

Scroll to Top