Concepts tested by this program: Generic Classes Utility Class (all static metho
ID: 3595122 • Letter: C
Question
Concepts tested by this program:
Generic Classes
Utility Class (all static methods)
New concepts tested by this program:
Linked Trees
Building a Tree for conversion purposes
Samuel F. B. Morse produced the first working telegraph set in 1836. This made transmission possible over any distance. The first Morse Code message, "What hath God wrought?", was sent from Washington to Baltimore.
Morse code was extensively used for early radio communication beginning in the 1890s.
In the early part of the twentieth century, the majority of high-speed international communication was conducted in Morse code, using telegraph lines, undersea cables, and radio circuits.
Morse code can also be transmitted using light which sometimes happens between ships at sea. It is used in emergencies to transmit distress signals when no other form of communication is available. The standard international distress signal is •••---••• (SOS).
Your assignment is to write a generic TreeNode class, a MorseCodeTree class and a MorseCodeConverter class. There is no GUI required for this assignment. Your classes will be tested with Junit tests.
TreeNode class
This generic class is used in the MorseCodeTree classes. The class consists of a reference to the data and a reference to the left and right child. Follow the Javadoc that is provided. The Javadoc only lists those public methods that are required to pass the Junit tests. You may add any private methods you need for your design.
MorseCodeTree class
A generic linked binary tree which inherits from the LinkedConverterTreeInterface. The class uses an external generic TreeNode class parameterized as a String: TreeNode. This class uses the private member of root. Nodes are added based on their morse code value. A ‘.’ (dot) means to traverse left and a ‘-‘ (dash) means to traverse right. The constructor will “build the tree”. Follow the Javadoc that is provided. The Javadoc only lists those public methods that are required to pass the Junit tests. You may add any private methods you need for your design.
Building the Data Structure (buildTree)
Your MorseCodeTree is a tree 4 levels. Insert a mapping for every letter of the alphabet into the tree map. The root is a TreeNode with an empty string. The left node at level 1 stores letter ‘e’ (code ‘.’) and the right node stores letter ‘t’ (code ‘-‘). The 4 nodes at level 2 are ‘i’, ‘a’, ‘n’, ‘m’ (code ‘..’, ‘.-‘, ‘-.’, ‘—‘). Insert into the tree by tree level from left to right. A ‘.’ will take the branch to the left and a ‘-‘ will take the branch to the right. This is the structure of the tree.
Using the Data Structure
Use the MorseCodeTree to convert Morse Code to English by taking the code and finding it’s corresponding English letter by traversing the MorseCodeTree, ‘.’ branches to the left and ‘-‘ branches to the right. The code ‘.--.’ would branch to the left, then to the right, then to the right, then to the left toFetch the letter ‘p’. Each letter is delimited by a space (‘ ‘). Each word is delimited by a ‘/’.
MorseCodeConverter – Utility Class
The MorseCodeConverter contains a static MorseCodeTree object and constructs (calls the constructor for) the MorseCodeTree.
This class has two static methods convertToEnglish to convert from morse code to English. One method is passed a string object (“.-.. --- ...- . / .-.. --- --- -.- ...”). The other method is passed a file to be converted. These static methods use the MorseCodeTree to convert from morse code to English characters. Each method returns a string object of English characters.
There is also a static printTree method that is used for testing purposes – to make sure the tree for MorseCodeTree was built properly.
Use the Javadoc provided to make sure that your MorseCodeConverter class follows the method headers so that the MorseCodeConverterTest will run correctly.
The JUnit Test Class
You must add at least 1 test for MorseCodeConverter.convertToEnglish(String) and at least 1 test for MorseCodeConverter.convertToEnglish(File) to the MorseCodeConverterTest class. Include your test file with your code files.
Test Cases:
Hello World
How do I love thee let me count the ways
Some suggestions:
Explanation / Answer
LinkedConverterTreeInterface.java
import java.util.ArrayList;
public interface LinkedConverterTreeInterface<T> {
public TreeNode<T> getRoot();
public void setRoot(TreeNode<T> newNode);
public LinkedConverterTreeInterface<T> insert(T code, T result);
public void addNode(TreeNode<T> root, T code, T letter);
public T fetch(String code);
public T fetchNode(TreeNode<T> root, T code);
public LinkedConverterTreeInterface<T> delete(T data) throws UnsupportedOperationException;
public LinkedConverterTreeInterface<T> update() throws UnsupportedOperationException;
public void buildTree();
public ArrayList<T> toArrayList();
public void LNRoutputTraversal(TreeNode<T> root, ArrayList<T> list);
}
MorseCodeConverter.java
import java.util.ArrayList;
import java.util.Scanner;
public class MorseCodeConverter
{
// Instance of the MorseCodeTree class, which will be used to perform the morse code translation
private static MorseCodeTree t = new MorseCodeTree();
public MorseCodeConverter()
{
}
public static java.lang.String convertToEnglish(java.lang.String code)
{
String output = "";
String[] word; // will hold each singular word from
String[] letter; // will hold each singular word from
// split each word in the current line into a new array.
word = code.split(" / ");
// loop through the array containing all the words of a line
for(int i = 0; i < word.length; i++)
{
//System.out.print(word[i]);
// split each letter in the current word into a new array.
letter = word[i].split(" ");
for(int j = 0; j < letter.length; j++)
{
//System.out.println(letter[j]);
output += t.fetch(letter[j]);
}
//add a space after each word has been translated
output += " ";
}
// take off preceeding or succedding spaces
output = output.trim();
return output;
}
public static java.lang.String convertToEnglish(java.io.File codeFile) throws java.io.FileNotFoundException
{
String output = "";
ArrayList<String> line = new ArrayList<String>();
String[] word; // will hold each singular word from
String[] letter; // will hold each singular word from
Scanner inputFile;
inputFile = new Scanner(codeFile);
// Read each content, line by line from the .txt file into a String ArrayList
while (inputFile.hasNext())
{
line.add(inputFile.nextLine());
}
inputFile.close();
// loop through the ArrayList containing all the lines
for(int i = 0; i < line.size(); i++)
{
//System.out.print(line.get(i));
// split each word in the current line into a new array.
word = line.get(i).split(" / ");
// loop through the array containing all the words of a line
for(int j = 0; j < word.length; j++)
{
//System.out.print(word[j]);
// split each letter in the current word into a new array.
letter = word[j].split(" ");
for(int k = 0; k < letter.length; k++)
{
//System.out.println(word[j]);
output += t.fetch(letter[k]);
}
//add a space after each word has been translated
output += " ";
}
}
// take off preceeding or succedding spaces
output = output.trim();
return output;
}
public static java.lang.String printTree()
{
ArrayList<String> treeData = new ArrayList<String>();
treeData = t.toArrayList();
String print = "";
for(int i = 0; i < treeData.size(); i ++)
{
print += treeData.get(i) + " ";
}
return print;
}
}
MorseCodeTree.java
import java.util.ArrayList;
public class MorseCodeTree implements LinkedConverterTreeInterface<java.lang.String>
{
private TreeNode<String> root = null; //root of the tree, which is set to null when the tree is empty
private String fetchedLetter; // variable to hold the String letter, which the fetch method will return
/**
* Constructor - calls the buildTree method
*/
public MorseCodeTree()
{
buildTree(); // call the buildTree method to create the tree, and place the letters for the morse code decoder in the correct position.
}
@Override
public void addNode(TreeNode<String> root, String code, String letter)
{
// If there is only one character in the morse code
if(code.length() == 1)
{
// if the character is '.' (dot) store to the left of the current root
if (code.equals("."))
{
root.lc = new TreeNode<String>(letter);
}
// else if the character is "-" (dash) store to the right of the current root
else
{
root.rc = new TreeNode<String>(letter);
}
return;
}
else
{
// if the first character is '.' (dot) new root becomes the left child
if(code.substring(0, 1).equals("."))
{
// recursively call addNode(new root, new code, letter)
//new code becomes all the remaining characters in the code (beyond the first character)
addNode(root.lc, code.substring(1), letter);
}
// else if the first character is "-" (dash) new root becomes the right child
else
{
// recursively call addNode(new root, new code, letter)
//new code becomes all the remaining characters in the code (beyond the first character)
addNode(root.rc, code.substring(1), letter);
}
}
}
@Override
public MorseCodeTree insert(java.lang.String code, java.lang.String letter)
{
// calls the recursive method addNode
addNode(root, code, letter);
return this;
}
@Override
public void buildTree()
{
//The root will have a value of "" (empty string)
root = new TreeNode<String>("");
// First Level
insert(".", "e");
insert("-", "t");
//Second Level
insert("..", "i");
insert(".-", "a");
insert("-.", "n");
insert("--", "m");
//Third Level
insert("...", "s");
insert("..-", "u");
insert(".-.", "r");
insert(".--", "w");
insert("-..", "d");
insert("-.-", "k");
insert("--.", "g");
insert("---", "o");
//Fourth Level
insert("....", "h");
insert("...-", "v");
insert("..-.", "f");
insert(".-..", "l");
insert(".--.", "p");
insert(".---", "j");
insert("-...", "b");
insert("-..-", "x");
insert("-.-.", "c");
insert("-.--", "y");
insert("--..", "z");
insert("--.-", "q");
}
/**
* Returns a reference to the root
* @return reference to root
*/
@Override
public TreeNode<String> getRoot()
{
return this.root;
}
@Override
public void setRoot(TreeNode<String> newNode) {
root = newNode;
}
@Override
public java.lang.String fetch(java.lang.String code)
{
// calls the recursive method fetchNode
String letter = fetchNode(root, code);
return letter;
}
/**
* This is the recursive method that fetches the data of the TreeNode that corresponds with the code
* A '.' (dot) means traverse to the left. A "-" (dash) means traverse to the right.
* The code ".-" would fetch the data of the TreeNode stored as the right child of the left child of the root
*
* @param root the root of the tree for this particular recursive instance of addNode
* @param code the code for this particular recursive instance of fetchNode
* @return the string (letter) corresponding to the code
*/
@Override
public java.lang.String fetchNode(TreeNode<java.lang.String> root, java.lang.String code)
{
// If there is only one character in the morse code
if(code.length() == 1)
{
// if the character is '.' (dot) retrieve the data from the left child of root
if (code.equals("."))
{
fetchedLetter = root.lc.getData();
}
// else if the character is '-' (dash) retrieve the data from the right child of root
else
{
fetchedLetter = root.rc.getData();
}
}
else
{
// if the first character is '.' (dot) new root becomes the left child
if(code.substring(0, 1).equals("."))
{
// recursively call fetchNode(new root, new code)
//new code becomes all the remaining characters in the code (beyond the first character)
fetchNode(root.lc, code.substring(1));
}
// if the first character is '-' (dash) new root becomes the right child
else
{
// recursively call fetchNode(new root, new code)
//new code becomes all the remaining characters in the code (beyond the first character)
fetchNode(root.rc, code.substring(1));
}
}
// Return the corresponding letter to the morse code
return fetchedLetter;
}
/**
* Returns an ArrayList of the items in the linked Tree in LNR (Inorder) Traversal order. Used for testing to make sure tree is built correctly
*
* @return an ArrayList of the items in the linked Tree
*/
@Override
public java.util.ArrayList<java.lang.String> toArrayList()
{
ArrayList<String> printTree = new ArrayList<String>();
LNRoutputTraversal(root, printTree);
return printTree;
}
/**
* The recursive method to put the contents of the tree in an ArrayList in LNR (Inorder)
*
* @param root the root of the tree for this particular recursive instance
* @param list the ArrayList that will hold the contents of the tree in LNR order
*/
@Override
public void LNRoutputTraversal(TreeNode<java.lang.String> root, java.util.ArrayList<java.lang.String> list)
{
if(root != null)
{
// recursive method to traverse through the binary tree in LNR (Inorder)
LNRoutputTraversal(root.lc, list);
list.add(root.getData());
LNRoutputTraversal(root.rc, list);
}
}
@Override
public LinkedConverterTreeInterface<String> delete(String data) throws UnsupportedOperationException {
return null;
}
@Override
public LinkedConverterTreeInterface<String> update() throws UnsupportedOperationException {
return null;
}
}
MorseCodeTreeTest.java
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class MorseCodeTreeTest {
MorseCodeTree tree = new MorseCodeTree();
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
tree = null;
}
@Test
public void testInsert() {
tree.insert(".----", "1");
// Now use the morse code for the number 1, to see if it fetches the correct number from the tree. This will let us know
// if it was added into the tree or not.
String letterFetched = tree.fetch(".----");
assertEquals("1", letterFetched);
}
@Test
public void testGetRoot() {
String root;
root = tree.getRoot().getData();
assertEquals("", root);
}
@Test
public void testSetRoot() {
String newRoot;
// the root is initially an empty string
assertEquals("", tree.getRoot().getData());
// Create a new node, which will be use to set as the new root
TreeNode<String> name = new TreeNode <String> ("Nabeel");
// Set the root to be the new node that was created
tree.setRoot(name);
newRoot = tree.getRoot().getData();
assertEquals("Nabeel", newRoot);
}
@Test
public void testFetch() {
// Since this method calls the recursive method fetchNode, it will act as a test for the fetchNode method as well.
String letterFetched;
// "-." is the morse code for the letter n.
letterFetched = tree.fetch("-.");
assertEquals("n", letterFetched);
String letterFetched2;
// "--.-" is the morse code for the letter q.
letterFetched2 = tree.fetch("--.-");
assertEquals("q", letterFetched2);
}
@Test
public void testToArrayList() {
// Since this method calls the LNRoutputTraversal method to arrange the ArrayList in inorder, it will act as a test for the LNRoutputTraversal method as well.
ArrayList<String> list = new ArrayList<String>();
list = tree.toArrayList();
assertEquals("h", list.get(0));
assertEquals("s", list.get(1));
assertEquals("v", list.get(2));
assertEquals("i", list.get(3));
assertEquals("f", list.get(4));
assertEquals("u", list.get(5));
assertEquals("e", list.get(6));
assertEquals("l", list.get(7));
assertEquals("r", list.get(8));
assertEquals("a", list.get(9));
assertEquals("p", list.get(10));
assertEquals("w", list.get(11));
assertEquals("j", list.get(12));
assertEquals("", list.get(13));
assertEquals("b", list.get(14));
assertEquals("d", list.get(15));
assertEquals("x", list.get(16));
assertEquals("n", list.get(17));
assertEquals("c", list.get(18));
assertEquals("k", list.get(19));
assertEquals("y", list.get(20));
assertEquals("t", list.get(21));
assertEquals("z", list.get(22));
assertEquals("g", list.get(23));
assertEquals("q", list.get(24));
assertEquals("m", list.get(25));
assertEquals("o", list.get(26));
}
}
TreeNode.java
public class TreeNode<T>
{
protected T data;
protected TreeNode<T> lc;
protected TreeNode<T> rc;
/**
* The constructor, which creates a new TreeNode with left and right child set to null and data set to the dataNode.
*
* @param dataNode the data to be stored in the TreeNode
*/
public TreeNode (T dataNode)
{
this.data = dataNode;
this.lc = null;
this.rc = null;
}
/**
* The constructor, which which will be used for making deep copies
*
* @param node the node to make copy of
*/
public TreeNode (TreeNode<T> node)
{
new TreeNode<T>(node);
}
/**
* Return the data within this TreeNode
*
* @return the data within the TreeNode
*/
public T getData()
{
return data;
}
}
MorseCodeConverterTest.java
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileNotFoundException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class MorseCodeConverterTest {
File inputFile;
File inputFileSTUDENT;
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testPrintTree()
{
//Note the extra space between j and b - that is because there is an empty string that
//is the root, and in the LNR traversal, the root would come between the right most
//child of the left tree (j) and the left most child of the right tree (b).
String correctResult = "h s v i f u e l r a p w j b d x n c k y t z g q m o";
String s = MorseCodeConverter.printTree();
s = s.trim(); // take off preceeding or succedding spaces
assertEquals(correctResult, s);
}
@Test
public void testConvertToEnglishString() {
String converter1 = MorseCodeConverter.convertToEnglish(".... . .-.. .-.. --- / .-- --- .-. .-.. -.. ");
assertEquals("hello world",converter1);
@SuppressWarnings("unused")
String test2="i love you";
String converter2 = MorseCodeConverter.convertToEnglish(".. / .-.. --- ...- . / -.-- --- ..- ");
assertEquals("i love you", converter2);
}
// My student test for testConvertToEnglishString
@Test
public void testConvertToEnglishStringSTUDENT() {
String converter1STUDENT = MorseCodeConverter.convertToEnglish("-- -.-- / -. .- -- . / .. ... / -. .- -... . . .-.. ");
assertEquals("my name is nabeel",converter1STUDENT);
String converter2STUDENT = MorseCodeConverter.convertToEnglish(". ...- . .-. -.-- -.. .- -.-- / .. ... / .- / --. .-. . .- - / -.. .- -.-- / - --- / -... . / .- .-.. .. ...- . ");
assertEquals("everyday is a great day to be alive", converter2STUDENT);
}
@Test
public void testConvertToEnglishFile() throws FileNotFoundException {
String test1="how do i love thee let me count the ways";
getFile("howDoILoveThee.txt");
String converter1 = MorseCodeConverter.convertToEnglish(inputFile);
assertEquals(test1,converter1);
String test2="love looks not with the eyes but with the mind";
getFile("LoveLooksNot.txt");
String converter2 = MorseCodeConverter.convertToEnglish(inputFile);
assertEquals(test2,converter2);
}
public void getFile(String in) throws FileNotFoundException {
JFileChooser chooser = new JFileChooser();
int status;
chooser.setDialogTitle("Select Input File - " + in);
status = chooser.showOpenDialog(null);
if(status == JFileChooser.APPROVE_OPTION)
{
try
{
inputFile = chooser.getSelectedFile();
// readFile();
}
catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
JOptionPane.showMessageDialog(null, "There is a problem with this file", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
// My student test for testConvertToEnglishFile
@Test
public void testConvertToEnglishFileSTUDENT() throws FileNotFoundException {
String test1STUDENT = "this is my student test file one";
getFileSTUDENT("StudentTestFile1.txt");
String converter1STUDENT = MorseCodeConverter.convertToEnglish(inputFileSTUDENT);
assertEquals(test1STUDENT,converter1STUDENT);
String test2STUDENT = "this is my student test file two";
getFileSTUDENT("StudentTestFile2.txt");
String converter2STUDENT = MorseCodeConverter.convertToEnglish(inputFileSTUDENT);
assertEquals(test2STUDENT,converter2STUDENT);
}
public void getFileSTUDENT(String in) throws FileNotFoundException {
JFileChooser chooser = new JFileChooser();
int status;
chooser.setDialogTitle("Select Input File - " + in);
status = chooser.showOpenDialog(null);
if(status == JFileChooser.APPROVE_OPTION)
{
try
{
inputFileSTUDENT = chooser.getSelectedFile();
// readFile();
}
catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
JOptionPane.showMessageDialog(null, "There is a problem with this file", "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.