Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • sarafa/p2
  • mertht/p2
  • cse332-19au/p2
  • sandchow/p2
  • hanzhang/p2
  • cse332-19sp/p2
  • cse332-20sp/p2
  • cse332-20su-tasks/p2
  • cse332-20su/p2
  • cse332-21su/p2
  • cse332-21wi/p2
  • cse332-21sp/p2
  • cse332-20au/p2
13 results
Show changes
Commits on Source (68)
Showing
with 402 additions and 301 deletions
/bin/
.DS_Store
.idea/
*.iml
No preview for this file type
This diff is collapsed.
......@@ -30,11 +30,6 @@ import org.alicebot.ab.MagicBooleans;
import org.alicebot.ab.MagicStrings;
import org.alicebot.ab.PCAIMLProcessorExtension;
import com.google.code.chatterbotapi.ChatterBot;
import com.google.code.chatterbotapi.ChatterBotFactory;
import com.google.code.chatterbotapi.ChatterBotSession;
import com.google.code.chatterbotapi.ChatterBotType;
import cse332.misc.WordReader;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
......@@ -53,7 +48,6 @@ public class ChatWindow {
private final StringBuilder content;
public String theirUsername;
public Chat esession;
public ChatterBotSession csession;
private final WordSuggestor[] markov;
private final UMessageServerConnection connection;
private final SpellingCorrector checker;
......@@ -86,38 +80,12 @@ public class ChatWindow {
this.esession = new Chat(bot);
}
else if (this.theirUsername.equals("cleverbot")) {
ChatterBotFactory factory = new ChatterBotFactory();
ChatterBot bot1;
try {
bot1 = factory.create(ChatterBotType.CLEVERBOT);
this.csession = bot1.createSession();
} catch (Exception e) {
}
}
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
try {
String path = new java.io.File(".").getCanonicalPath();
this.content.append("<link rel='stylesheet' type='text/css' href='file:///"
+ path + "/chat.css'>");
this.content.append("<head>");
this.content.append(
" <script language=\"javascript\" type=\"text/javascript\">");
this.content.append(" function toBottom(){");
this.content
.append(" window.scrollTo(0, document.body.scrollHeight);");
this.content.append(" }");
this.content.append(" </script>");
this.content.append("</head>");
this.content.append("<body onload='toBottom()'>");
} catch (IOException e1) {
}
private void initialize() {
this.frame = new JFrame();
this.frame.setBounds(100, 100, 290, 390);
this.frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
......@@ -137,17 +105,28 @@ public class ChatWindow {
gbc_msgScrollPane.gridx = 0;
gbc_msgScrollPane.gridy = 0;
this.chatMessagesPanel = new JFXPanel();
this.frame.getContentPane().add(this.chatMessagesPanel, gbc_msgScrollPane);
Platform.runLater(() -> {
ChatWindow.this.chatMessages = new WebView();
BorderPane borderPane = new BorderPane();
borderPane.setCenter(ChatWindow.this.chatMessages);
Scene scene = new Scene(borderPane, 450, 450);
ChatWindow.this.chatMessagesPanel.setScene(scene);
});
show();
(new Thread() {
public void run() {
try {
String path = new java.io.File(".").getCanonicalPath();
content.append("<link rel='stylesheet' type='text/css' href='file:///"
+ path + "/chat.css'>");
content.append("<head>");
content.append(
" <script language=\"javascript\" type=\"text/javascript\">");
content.append(" function toBottom(){");
content
.append(" window.scrollTo(0, document.body.scrollHeight);");
content.append(" }");
content.append(" </script>");
content.append("</head>");
content.append("<body onload='toBottom()'>");
} catch (IOException e1) {
}
}
}).start();
JPanel suggestionsPanel = new JPanel();
GridBagConstraints gbc_suggestionsPanel = new GridBagConstraints();
......@@ -269,11 +248,29 @@ public class ChatWindow {
}
};
this.frame.addKeyListener(giveFocus);
this.chatMessagesPanel.addKeyListener(giveFocus);
suggestionsPanel.addKeyListener(giveFocus);
myMessagePanel.addKeyListener(giveFocus);
(new Thread() {
public void run() {
chatMessagesPanel = new JFXPanel();
chatMessagesPanel.addKeyListener(giveFocus);
frame.getContentPane().add(chatMessagesPanel, gbc_msgScrollPane);
Platform.runLater(() -> {
ChatWindow.this.chatMessages = new WebView();
BorderPane borderPane = new BorderPane();
borderPane.setCenter(ChatWindow.this.chatMessages);
Scene scene = new Scene(borderPane, 450, 450);
ChatWindow.this.chatMessagesPanel.setScene(scene);
});
}
}).start();
this.frame.pack();
show();
this.myMessage.requestFocusInWindow();
}
......@@ -322,13 +319,15 @@ public class ChatWindow {
String text = ("SOL " + this.myMessage.getText()).trim();
int lastSpace = text.lastIndexOf(' ');
String allButLast = lastSpace > -1 ? text.substring(0, lastSpace) : null;
this.undo = this.myMessage.getText();
String newText = (allButLast.replaceAll("SOL", "") + " " + result).trim();
if (this.myMessage.getText().startsWith(newText)) {
return false;
if (allButLast != null) {
this.undo = this.myMessage.getText();
String newText = (allButLast.replaceAll("SOL", "") + " " + result).trim();
if (this.myMessage.getText().startsWith(newText)) {
return false;
}
this.myMessage.setText(newText);
return true;
}
this.myMessage.setText(newText);
return true;
}
return false;
}
......@@ -374,13 +373,6 @@ public class ChatWindow {
receiveMessage(this.esession.multisentenceRespond(msg));
return;
}
else if (this.theirUsername.equals("cleverbot")) {
try {
receiveMessage(this.csession.think(msg));
return;
} catch (Exception e) {
}
}
else {
try {
this.connection.m_channel(this.theirUsername, msg);
......
......@@ -15,7 +15,6 @@ import javax.swing.JList;
import p2.wordsuggestor.WordSuggestor;
public class MainWindow {
private JFrame frame;
private List<String> usernames;
private final List<ChatWindow> chats;
......@@ -51,27 +50,30 @@ public class MainWindow {
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
@SuppressWarnings("unchecked")
JList<String> list = (JList<String>) e.getSource();
if (e.getClickCount() == 2) {
int index = list.locationToIndex(e.getPoint());
for (ChatWindow client : MainWindow.this.chats) {
if (client.theirUsername
.equals(MainWindow.this.usernames.get(index))) {
client.show();
return;
(new Thread() {
public void run() {
@SuppressWarnings("unchecked")
JList<String> list = (JList<String>) e.getSource();
if (e.getClickCount() == 2) {
int index = list.locationToIndex(e.getPoint());
for (ChatWindow client : MainWindow.this.chats) {
if (client.theirUsername
.equals(MainWindow.this.usernames.get(index))) {
client.show();
return;
}
}
MainWindow.this.chats
.add(new ChatWindow(MainWindow.this.usernames.get(index),
MainWindow.this.markov, MainWindow.this.connection));
}
}
MainWindow.this.chats
.add(new ChatWindow(MainWindow.this.usernames.get(index),
MainWindow.this.markov, MainWindow.this.connection));
}
}).start();
}
});
this.usernames = new ArrayList<String>();
this.usernames.add("cleverbot");
this.usernames.add("eliza");
this.model = new UsersModel(this.usernames);
list.setModel(this.model);
......@@ -86,6 +88,9 @@ public class MainWindow {
}
usersSet.remove(this.username);
this.usernames = new ArrayList<String>(usersSet);
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
this.model.update(this.usernames);
}
......
......@@ -6,16 +6,24 @@ import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.BorderLayout;
import java.io.IOException;
import java.util.function.Supplier;
import javax.swing.Box;
import javafx.embed.swing.JFXPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JDialog;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import cse332.interfaces.misc.Dictionary;
import cse332.types.AlphabeticString;
......@@ -62,35 +70,66 @@ public class uMessage {
}
@Override
public void run() {
int N = uMessage.N;
try {
uMessage.markov[this.i] = new WordSuggestor(uMessage.CORPUS, N - this.i,
4, uMessage.NEW_OUTER, uMessage.NEW_INNER);
uMessage.loading[this.i] = false;
this.window.update();
} catch (IOException e) {
public void run() {
int N = uMessage.N;
try {
uMessage.markov[this.i] = new WordSuggestor(uMessage.CORPUS, N - this.i,
4, uMessage.NEW_OUTER, uMessage.NEW_INNER);
this.window.update();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
final uMessage window = new uMessage();
window.frmUmessageLogin.setVisible(true);
window.errors.setText("Loading the Markov Data (n = " + uMessage.N + ")...");
uMessage.markov = new WordSuggestor[uMessage.N];
uMessage.loading = new boolean[uMessage.N];
for (int i1 = 0; i1 < uMessage.N; i1++) {
uMessage.loading[i1] = true;
(new Thread() {
public void run() {
new JFXPanel();
}
for (int i2 = 0; i2 < uMessage.N; i2++) {
new Thread(new MarkovLoader(window, i2)).start();
}).start();
final uMessage window = new uMessage();
markov = new WordSuggestor[uMessage.N];
JDialog dialog = new JDialog((JFrame)null, "Please wait...", true);//true means that the dialog created is modal
JLabel lblStatus = new JLabel("<html><b>Loading Markov Data (n = " + uMessage.N + ")...</b><br>Depending on the data structures you're using<br>" +
"and your computer, this might take a bit.</html>");
JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setIndeterminate(true); //we'll use an indeterminate progress bar
dialog.add(BorderLayout.NORTH, lblStatus);
dialog.add(BorderLayout.CENTER, pbProgress);
dialog.addWindowListener(new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
dialog.setSize(300, 90);
SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
for (int i2 = 1; i2 < uMessage.N; i2++) {
new Thread(new MarkovLoader(window, i2)).start();
}
new MarkovLoader(window, 0).run();
return null;
}
@Override
protected void done() {
dialog.dispose();//close the modal dialog
window.frmUmessageLogin.setVisible(true);
}
};
sw.execute(); // this will start the processing on a separate thread
dialog.setVisible(true); //this will block user input as long as the processing task is working
}
/**
......@@ -112,7 +151,7 @@ public class uMessage {
gridBagLayout.columnWidths = new int[] { 0, 90, 90, 90, 0, 0 };
gridBagLayout.rowHeights = new int[] { 0, 9, 0, 0 };
gridBagLayout.columnWeights = new double[] { 0.0, 0.0, 1.0, 0.0, 0.0,
Double.MIN_VALUE };
Double.MIN_VALUE };
gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, Double.MIN_VALUE };
this.frmUmessageLogin.getContentPane().setLayout(gridBagLayout);
......@@ -131,7 +170,7 @@ public class uMessage {
this.frmUmessageLogin.getContentPane().add(this.horizontalStrut,
gbc_horizontalStrut);
JLabel usernameLabel = new JLabel("Username:");
JLabel usernameLabel = new JLabel("UWnetID:");
GridBagConstraints gbc_usernameLabel = new GridBagConstraints();
gbc_usernameLabel.fill = GridBagConstraints.BOTH;
gbc_usernameLabel.insets = new Insets(0, 0, 5, 5);
......@@ -143,10 +182,14 @@ public class uMessage {
this.username.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (update() && e.getKeyCode() == KeyEvent.VK_ENTER) {
uMessage.this.login.setEnabled(false);
login();
}
(new Thread() {
public void run() {
if (update() && e.getKeyCode() == KeyEvent.VK_ENTER) {
uMessage.this.login.setEnabled(false);
login();
}
}
}).start();
}
});
......@@ -187,14 +230,6 @@ public class uMessage {
}
public boolean update() {
boolean noneLoading = true;
for (int i = 0; i < uMessage.loading.length; i++) {
noneLoading &= !uMessage.loading[i];
}
if (noneLoading) {
this.errors.setText("");
this.errors.setForeground(Color.BLACK);
}
if (!this.loggingIn && this.username.getText().length() > 0) {
this.login.setEnabled(true);
this.errors.setForeground(Color.BLACK);
......@@ -210,11 +245,10 @@ public class uMessage {
this.loggingIn = true;
update();
try {
this.connection = new UMessageServerConnection(this,
this.username.getText().replaceAll(" ", ""));
this.connection.go();
} catch (IOException e1) {
}
connection = new UMessageServerConnection(uMessage.this,
username.getText().replaceAll(" ", ""));
connection.go();
} catch (IOException e1) {}
}
public void badNick() {
......@@ -225,19 +259,6 @@ public class uMessage {
}
public void loggedIn(String username) {
boolean noneLoading = false;
while (!noneLoading) {
noneLoading = true;
for (int i = 0; i < uMessage.loading.length; i++) {
noneLoading &= !uMessage.loading[i];
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
this.frmUmessageLogin.dispose();
this.window = new MainWindow(username, uMessage.markov, this.connection);
this.loggingIn = false;
......
......@@ -35,9 +35,11 @@ public class BinarySearchTree<K extends Comparable<K>, V>
public BSTNode[] children; // The children of this node.
/**
* Create a new data node and increment the enclosing tree's size.
* Create a new data node.
*
* @param data
* @param key
* key with which the specified value is to be associated
* @param value
* data element to be stored at this node.
*/
@SuppressWarnings("unchecked")
......@@ -47,7 +49,7 @@ public class BinarySearchTree<K extends Comparable<K>, V>
}
}
private BSTNode find(K key, V value) {
protected BSTNode find(K key, V value) {
BSTNode prev = null;
BSTNode current = this.root;
......@@ -58,9 +60,6 @@ public class BinarySearchTree<K extends Comparable<K>, V>
// We found the key!
if (direction == 0) {
if (value != null) {
current.value = value;
}
return current;
}
else {
......@@ -71,9 +70,9 @@ public class BinarySearchTree<K extends Comparable<K>, V>
}
}
// If value is null, we need to actually add in the new value
// If value is not null, we need to actually add in the new value
if (value != null) {
current = new BSTNode(key, value);
current = new BSTNode(key, null);
if (this.root == null) {
this.root = current;
}
......@@ -90,6 +89,9 @@ public class BinarySearchTree<K extends Comparable<K>, V>
@Override
public V find(K key) {
if (key == null) {
throw new IllegalArgumentException();
}
BSTNode result = find(key, null);
if (result == null) {
return null;
......@@ -99,7 +101,13 @@ public class BinarySearchTree<K extends Comparable<K>, V>
@Override
public V insert(K key, V value) {
return find(key, value).value;
if (key == null || value == null) {
throw new IllegalArgumentException();
}
BSTNode current = find(key, value);
V oldValue = current.value;
current.value = value;
return oldValue;
}
@Override
......
......@@ -6,7 +6,7 @@ import java.util.Iterator;
import cse332.interfaces.worklists.FixedSizeFIFOWorkList;
import datastructures.worklists.CircularArrayFIFOQueue;
public abstract class BString<Alphabet extends Comparable<Alphabet> implements Iterable<Alphabet>, Comparable<BString<Alphabet>> {
public abstract class BString<Alphabet extends Comparable<Alphabet>> implements Iterable<Alphabet>, Comparable<BString<Alphabet>> {
protected FixedSizeFIFOWorkList<Alphabet> str;
public BString(Alphabet[] str) {
......@@ -26,7 +26,7 @@ public abstract class BString<Alphabet extends Comparable<Alphabet> implements I
}
@SuppressWarnings("unchecked")
public static <A, X extends BString<A>> Class<A> getLetterType(Class<X> clz) {
public static <A extends Comparable<A>, X extends BString<A>> Class<A> getLetterType(Class<X> clz) {
try {
return (Class<A>) clz.getMethod("getLetterType", (Class<?>[]) null)
.invoke(null, (Object[]) null);
......
......@@ -89,22 +89,23 @@ public abstract class WorkList<E> implements Iterable<E> {
}
/**
* Note that the toString() method of a WorkList _consumes_ the WorkList.
* This can lead to odd and unpredictable behavior.
*
* @postcondition hasWork() is false
* Returns some basic information about this particular worklist.
*
* Calling this method does not consume the worklist.
*
* @return a string representation of this worklist
*/
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append("[");
while (this.hasWork()) {
result.append(this.next().toString() + ", ");
}
if (result.length() > 1) {
result.replace(result.length() - 2, result.length(), "");
if (this.hasWork()) {
return String.format("%s(size = %d, peek = %s)",
this.getClass().getSimpleName(),
this.size(),
this.peek());
} else {
return String.format("%s(size = %d)",
this.getClass().getSimpleName(),
this.size());
}
result.append("]");
return result.toString();
}
}
......@@ -6,7 +6,7 @@ import cse332.datastructures.trees.BinarySearchTree;
* TODO: Replace this comment with your own as appropriate.
*
* AVLTree must be a subclass of BinarySearchTree<E> and must use
* inheritance and callst o superclass methods to avoid unnecessary
* inheritance and calls to superclass methods to avoid unnecessary
* duplication or copying of functionality.
*
* 1. Create a subclass of BSTNode, perhaps named AVLNode.
......
......@@ -14,11 +14,16 @@ import cse332.interfaces.misc.Dictionary;
* restrict the size of the input domain (i.e., it must accept
* any key) or the number of inputs (i.e., it must grow as necessary).
* 3. Your HashTable should rehash as appropriate (use load factor as
* shown in class).
* 5. HashTable should be able to grow at least up to 200,000 elements.
* shown in class!).
* 5. HashTable should be able to resize its capacity to prime numbers for more
* than 200,000 elements. After more than 200,000 elements, it should
* continue to resize using some other mechanism.
* 6. We suggest you hard code some prime numbers. You can use this
* list: http://primes.utm.edu/lists/small/100000.txt
* NOTE: Do NOT copy the whole list!
* 7. When implementing your iterator, you should NOT copy every item to another
* dictionary/list and return that dictionary/list's iterator.
*/
public class ChainingHashTable<K, V> extends DeletelessDictionary<K, V> {
private Supplier<Dictionary<K, V>> newChain;
......
......@@ -9,14 +9,16 @@ import cse332.interfaces.misc.DeletelessDictionary;
/**
* TODO: Replace this comment with your own as appropriate.
* 1. The list is typically not sorted.
* 2. Add new items to the front oft he list.
* 2. Add new items to the front of the list.
* 3. Whenever find is called on an item, move it to the front of the
* list. This means you remove the node from its current position
* and make it the first node in the list.
* 4. You need to implement an iterator. The iterator SHOULD NOT move
* elements to the front. The iterator should return elements in
* the order they are stored in the list, starting with the first
* element in the list.
* element in the list. When implementing your iterator, you should
* NOT copy every item to another dictionary/list and return that
* dictionary/list's iterator.
*/
public class MoveToFrontList<K, V> extends DeletelessDictionary<K, V> {
@Override
......
......@@ -3,10 +3,12 @@ package p2.clients;
import java.io.IOException;
import java.util.function.Supplier;
import cse332.datastructures.trees.BinarySearchTree;
import cse332.interfaces.misc.BString;
import cse332.interfaces.misc.Dictionary;
import cse332.types.AlphabeticString;
import cse332.types.NGram;
import datastructures.dictionaries.AVLTree;
import datastructures.dictionaries.ChainingHashTable;
import datastructures.dictionaries.HashTrieMap;
import p2.wordsuggestor.WordSuggestor;
......@@ -20,6 +22,17 @@ public class NGramTester {
Supplier<Dictionary<K, V>> constructor) {
return () -> new ChainingHashTable<K, V>(constructor);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <K, V> Supplier<Dictionary<K, V>> binarySearchTreeConstructor() {
return () -> new BinarySearchTree();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <K, V> Supplier<Dictionary<K, V>> avlTreeConstructor() {
return () -> new AVLTree();
}
public static void main(String[] args) {
try {
......
package p2.wordsuggestor;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Stack;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import cse332.interfaces.worklists.LIFOWorkList;
import datastructures.worklists.ArrayStack;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.json.simple.JSONArray;
public final class ParseFBMessages {
private ParseFBMessages() {
/* should not be instantiated */ }
// INSTRUCTIONS:
//
// <Your FB Name> may be either:
// 1) Your name on Messenger (e.g. "Danny Allen")
// 2) Your username on facebook, which can be found by looking at the URL on your profile
// It's typically 1), but for whatever reason Facebook sometimes labels them
// with 2) (sorry!). You can check which one your messages are labeled with by
// opening up one of the message files and taking a look.
//
// <Your FB Archive> is the directory on your computer where the archive is stored.
// (e.g. "/Users/Me/Downloads/MyArchiveName" or "C:\Users\Me\Downloads\MyArchiveName")
// You may be able to use a relative path like "./MyArchiveName", but results can
// vary from machine to machine.
//
// DO NOT PUSH YOUR ME.TXT FILE TO GITLAB. WE DO NOT WANT YOUR PRIVATE CONVERSATIONS!!!!
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.out.println("USAGE: ParseFBMessages <Your FB Name> <Your FB Archive>");
System.exit(1);
}
String name = args[0];
String archive = args[1];
String name = "<Your FB Name>"; // e.g. "Ruth Anderson"
String archive = "<Your FB Archive>"; // e.g. "/Users/rea/workspace/332/facebook-rea/messages"
LIFOWorkList<String> messages = new ArrayStack<String>();
Document doc = Jsoup
.parse(new File(archive + File.separator + "html/messages.htm"), "UTF-8");
Elements messagesElements = doc.getElementsByTag("p");
Stack<String> corpus = new Stack<>();
File[] listOfFiles = (new File(archive + File.separator + "inbox")).listFiles();
for (Element content : messagesElements) {
if (content.previousElementSibling().getElementsByClass("user").text()
.equals(name)) {
messages.add(content.text());
for (int i = 0; i < listOfFiles.length; i++) {
File conversation = new File(listOfFiles[i], "message.json");
if (conversation.isFile()) {
try {
JSONObject obj = (JSONObject) new JSONParser().parse(new FileReader(conversation));
JSONArray messages = (JSONArray) obj.get("messages");
for (Object m: messages) {
JSONObject msg = (JSONObject) m;
String sender = (String) msg.get("sender_name");
if(sender != null && sender.equals(name)) {
corpus.push((String) msg.get("content"));
}
}
} catch (ParseException e) {
System.err.println("Could not parse: " + conversation.toString());
}
}
}
PrintWriter out = new PrintWriter("me.txt", "UTF-8");
while (messages.hasWork()) {
out.println(messages.next());
while (!corpus.isEmpty()) {
out.println(corpus.pop());
}
out.close();
......
......@@ -15,7 +15,6 @@ import datastructures.worklists.ArrayStack;
/**
* An executable that generates text in the style of the provided input file.
* You will need to modify this file.
*/
public class WordSuggestor {
private final int N, K;
......@@ -73,6 +72,12 @@ public class WordSuggestor {
words[i] = allWords.next();
i--;
}
for (i = 0; i < words.length; i++) {
if (words[i] == null) {
words[i] = "NULL";
}
}
return new NGram(words);
}
......
# Project 2 (uMessage) Write-Up #
--------
## Project Enjoyment ##
- How Was Your Partnership?
<pre>TODO</pre>
- What was your favorite part of the project?
<pre>TODO</pre>
- What was your least favorite part of the project?
<pre>TODO</pre>
- How could the project be improved?
<pre>TODO</pre>
- Did you enjoy the project?
<pre>TODO</pre>
-----
## Experiments ##
Throughout p1 and p2, you have written (or used) several distinct implementations of the Dictionary interface:
- HashTrieMap
- MoveToFrontList
- BinarySearchTree
- AVLTree
- ChainingHashTable
In this Write-Up, you will compare various aspects of these data structures. This will take a significant amount of
time, and you should not leave it to the last minute. For each experiment, we expect you to:
- Explain how you constructed the inputs to make your conclusions
- Explain why your data supports your conclusions
- Explain your methodology (e.g., if we wanted to re-run your experiment, we would be able to)
- Include the inputs themselves in the experiments folder
- Include your data either directly in the write-up or in the experiments folder
- If you think it helps your explanation, you can include graphs of the outputs (we recommend that you do this for some of them)
- We recommend that you keep your "N" (as in "N-gram") constant throughout these experiments. (N = 2 and N = 3 are reasonable.)
### BST vs. AVLTree ###
Construct input files to NGramTester of your choosing to demonstrate that an AVL Tree is asymptotically better
than a Binary Search Tree.
<pre>TODO</pre>
### BST Worst Case vs. BST Best Case ###
We know that the worst case for a BST insertion is O(n) and the best case is O(lg n). Construct input
files of your choosing that demonstrate these best and worst cases for a large n. How big is the difference?
Is it surprising?
<pre>TODO</pre>
### ChainingHashTable ###
Your ChainingHashTable should take as an argument to its constructor the type of "chains" it uses. Determine
which type of chain is (on average) best: an MTFList, a BST, or an AVL Tree. Explain your intuition on why
the answer you got makes sense (or doesn't!).
<pre>TODO</pre>
### Hash Functions ###
Write a new hash function (it doesn't have to be any good, but remember to include the code in your repository).
Compare the runtime of your ChainingHashTable when the hash function is varied. How big of a difference can the
hash function make? (You should keep all other inputs (e.g., the chain type) constant.)
<pre>TODO</pre>
### General Purpose Dictionary ###
Compare all of the dictionaries (on their best settings, as determined above) on several large input files. Is
there a clear winner? Why or why not? Is the winner surprising to you?
<pre>TODO</pre>
### General Sorts ###
You have several general purpose sorts (InsertionSort, HeapSort, TopKSort). We would like you to compare these
sorts using *step counting*. That is, for all other experiments, you likely compared the time it took for the various
things to run, but for this one, we want you to (1) choose a definition of step, (2) modify the sorting algorithms to
calculate the number of steps, and (3) compare the results. In this case, there is a "good" definition of step, and
there are many bad ones. We expect you to justify your choice.
<pre>TODO</pre>
### Top K Sort ###
TopKSort should theoretically be better for small values of k. Determine (using timing or step-counting--your choice)
which n (input size) and k (number of elements sorted) makes TopKSort worthwhile over your best sort from the previous
experiment.
<pre>TODO</pre>
### uMessage ###
Use uMessage to test out your implementations. Using N=3, uMessage should take less than a minute to load using
your best algorithms and data structures on a reasonable machine.
- How are the suggestions uMessage gives with the default corpus?
<pre>TODO</pre>
- Now, switch uMessage to use a corpus of YOUR OWN text. To do this, you will need a corpus.
You can use anything you like (Facebook, google talk, e-mails, etc.) We provide
instructions and a script to format Facebook data correctly as we expect it will be the most common
choice. If you are having problems getting data, please come to office hours and ask for help.
Alternatively, you can concatenate a bunch of English papers you've written together to get a corpus
of your writing. PLEASE DO NOT INCLUDE "me.txt" IN YOUR REPOSITORY. WE DO NOT WANT YOUR PRIVATE CONVERSATIONS.
* Follow these instructions to get your Facebook data: https://www.facebook.com/help/212802592074644
* Run the ParseFBMessages program in the main package.
* Use the output file "me.txt" as the corpus for uMessage.
- How are the suggestions uMessage gives wth the new corpus?
<pre>TODO</pre>
-----
## Above and Beyond ##
- Did you do any Above and Beyond? Describe exactly what you implemented.
<pre>TODO</pre>
\ No newline at end of file
......@@ -23,7 +23,7 @@ public class CircularArrayComparatorTests extends TestsUtility {
test("test_a_aa");
test("test_equality_consistent_with_compare");
test("test_compare_transitive");
test("test_equals_doesnt_modify");
finish();
}
......@@ -110,4 +110,13 @@ public class CircularArrayComparatorTests extends TestsUtility {
l2.add("b");
return l1.equals(l2) && l1.compareTo(l2) == 0 ? 1 : 0;
}
public static int test_equals_doesnt_modify() {
CircularArrayFIFOQueue<String> l1 = init();
CircularArrayFIFOQueue<String> l2 = init();
l1.add("a");
l2.add("a");
l1.equals(l2);
return l1.size() == 1 ? 1 : 0;
}
}
......@@ -2,13 +2,9 @@ package tests.gitlab.ckpt1;
import java.util.Arrays;
import cse332.datastructures.*;
import cse332.datastructures.containers.Item;
import cse332.interfaces.*;
import datastructures.dictionaries.MoveToFrontList;
import tests.TestsUtility;
import tests.datastructures.IntegerComparator;
import tests.exceptions.InformativeException;
public class MoveToFrontListTests extends TestsUtility {
public static void main(String[] args) {
......
......@@ -2,7 +2,7 @@ package tests.gitlab.ckpt1;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Map;
import java.util.function.Supplier;
......@@ -10,16 +10,16 @@ import cse332.datastructures.containers.Item;
import cse332.interfaces.misc.Dictionary;
import cse332.types.AlphabeticString;
import cse332.types.NGram;
import datastructures.dictionaries.HashTrieMap;
import cse332.datastructures.trees.BinarySearchTree;
import p2.wordsuggestor.NGramToNextChoicesMap;
import tests.TestsUtility;
public class NGramToNextChoicesMapTests extends TestsUtility {
private static Supplier<Dictionary<NGram, Dictionary<AlphabeticString, Integer>>> newOuter =
() -> new HashTrieMap<String, NGram, Dictionary<AlphabeticString, Integer>>(NGram.class);
() -> new BinarySearchTree();
private static Supplier<Dictionary<AlphabeticString, Integer>> newInner =
() -> new HashTrieMap<Character, AlphabeticString, Integer>(AlphabeticString.class);
private static Supplier<Dictionary<AlphabeticString, Integer>> newInner =
() -> new BinarySearchTree();
public static void main(String[] args) {
new NGramToNextChoicesMapTests().run();
......@@ -95,7 +95,7 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
if (items.length != answer.length) return 0;
String[] itemsWithoutCounts = new String[items.length];
for (int j = 0; j < answer.length; j++) {
if (items[j].value != 1) return 0;
if (!items[j].value.equals(1)) return 0;
itemsWithoutCounts[j] = items[j].key;
}
Arrays.sort(itemsWithoutCounts);
......@@ -127,10 +127,10 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
return 1;
}
// TODO: Not finished yet
@SuppressWarnings("unchecked")
public static int testRepeatedWordsPerNGram() {
NGramToNextChoicesMap map = init();
// Creates Ngrams to test for with N = 3
NGram[] ngrams = new NGram[]{
new NGram(new String[]{"foo", "bar", "baz"}),
new NGram(new String[]{"fee", "fi", "fo"}),
......@@ -138,7 +138,7 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
new NGram(new String[]{"3", "2", "2"}),
new NGram(new String[]{"a", "s", "d"})
};
// Array of words seen after each Ngram with correlating index from above
String[][] words = new String[][] {
new String[]{"bop", "bip", "boop", "bop", "bop"},
new String[]{"fum", "giants", "giants"},
......@@ -148,7 +148,10 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
};
// yes this is awful, but i can't think of a better way to do it atm
Map<NGram, Item<String, Integer>[]> answers = new HashMap<>();
// Creates answers for getCountsAfter - Word seen after and count
// corrlates with words and ngrams above
// Note that words after are in sorted order, not in order of array in words
Map<NGram, Item<String, Integer>[]> answers = new TreeMap<>();
answers.put(ngrams[0], (Item<String, Integer>[]) new Item[3]);
answers.get(ngrams[0])[0] = new Item<String, Integer>("bip", 1);
answers.get(ngrams[0])[1] = new Item<String, Integer>("boop", 1);
......@@ -167,12 +170,14 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
answers.get(ngrams[4])[1] = new Item<String, Integer>("for", 2);
answers.get(ngrams[4])[2] = new Item<String, Integer>("while", 2);
// Adds nGrams and words after to student's NGramToNextChoicesMap
for (int i = 0; i < ngrams.length; i++) {
for (int j = 0; j < words[i].length; j++) {
map.seenWordAfterNGram(ngrams[i], words[i][j]);
}
}
// checks to see if getCountsAfter returns correctly
for (int i = 0; i < ngrams.length; i++) {
NGram ngram = ngrams[i];
Item<String, Integer>[] results = map.getCountsAfter(ngram);
......@@ -187,12 +192,15 @@ public class NGramToNextChoicesMapTests extends TestsUtility {
});
Item<String, Integer>[] expected = answers.get(ngram);
// checks for correct number of unique words after
if (results.length != expected.length) return 0;
for (int j = 0; j < expected.length; j++) {
// checks if correct word after via sorted words
if (!expected[j].key.equals(results[j].key)) {
return 0;
}
if (expected[j].value != results[j].value) {
// checks if correct count for given word after
if (!expected[j].value.equals(results[j].value)) {
return 0;
}
}
......