From 29c8c79367261aa9bd04a4347a014d2d28ea5da1 Mon Sep 17 00:00:00 2001 From: gzwongkk Date: Fri, 27 Oct 2017 17:08:48 +0800 Subject: [PATCH 1/5] Upload solution of lab 5 --- lab6/solution/Adapter.java | 24 +++++++++++ lab6/solution/Observer.java | 31 ++++++++++++++ lab6/solution/Subject.java | 60 +++++++++++++++++++++++++++ lab6/solution/Test.java | 70 ++++++++++++++++++++++++++++++++ lab6/solution/WagnerFischer.java | 45 ++++++++++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 lab6/solution/Adapter.java create mode 100644 lab6/solution/Observer.java create mode 100644 lab6/solution/Subject.java create mode 100644 lab6/solution/Test.java create mode 100644 lab6/solution/WagnerFischer.java diff --git a/lab6/solution/Adapter.java b/lab6/solution/Adapter.java new file mode 100644 index 000000000..e0baf3891 --- /dev/null +++ b/lab6/solution/Adapter.java @@ -0,0 +1,24 @@ +package solution; + +public class Adapter { + public static final String[] BEVERAGES = new String[] { + "Caffè Americano", "Caffè Mocha", "Caffè Latte", + "Cappuccino", "Caramel Macchiato", "Espresso" }; + + public String getBeverage(String s){ + // Return null if nothing is similar + int min = Integer.MAX_VALUE; + String min_string = null; + // Compare each word in the array with the query word + for ( String b : BEVERAGES ) { + WagnerFischer ob = new WagnerFischer( s, b ); + int dist = ob.getDistance(); + // Record the minimum + if ( dist <= 3 && dist < min ) { + min = dist; + min_string = b; + } + } + return min_string; + } +} diff --git a/lab6/solution/Observer.java b/lab6/solution/Observer.java new file mode 100644 index 000000000..950a5143b --- /dev/null +++ b/lab6/solution/Observer.java @@ -0,0 +1,31 @@ +package solution; + +public class Observer { + private int id; + private Subject subject; + + public Observer(int id) { + this.id = id; + } + + public int getID(){ + return id; + } + + public void subscribe(Subject sub) { + this.subject = sub; + } + + public void unsubscribe() { + subject.unregister(this); + } + + public void update(){ + // Get the message first + int order = Integer.valueOf(subject.getMessage()); + // React based on the message + if ( order >= getID()+7 || order == getID() ) { + unsubscribe(); + } + } +} diff --git a/lab6/solution/Subject.java b/lab6/solution/Subject.java new file mode 100644 index 000000000..f7c483be1 --- /dev/null +++ b/lab6/solution/Subject.java @@ -0,0 +1,60 @@ +package solution; + +import java.util.ArrayList; +import java.util.List; + +public class Subject { + private List observers; + private String message; + private boolean changed; + + public Subject() { + observers = new ArrayList(); + message = null; + changed = false; + } + + public void register(Observer obj) { + if ( !observers.contains(obj) ) observers.add(obj); + } + + public void unregister(Observer obj) { + observers.remove(obj); + } + + public void notifyObservers() { + // if nothing is changed, we can skip this + if ( !changed ) return; + + // we need to use a new list because observers may unsubscribe from the list + // and this might cause unexpected behaviours + // forEach is a faster way to loop over a list (see Java 1.8 lambda expression) + new ArrayList<>(observers).forEach( o -> o.update() ); + + // another approach to do it is to traverse the list starting from the end + for ( int i = observers.size()-1; i >= 0; --i ) { + observers.get(i).update(); + } + + // reset parameter + changed = false; + } + + public void setMessage(String msg) { + this.message=msg; + this.changed=true; + notifyObservers(); + } + + public String getMessage() { + return message; + } + + public void setChanged(boolean changed) { + this.changed = changed; + } + + public List getQueue() { + return observers; + } +} diff --git a/lab6/solution/Test.java b/lab6/solution/Test.java new file mode 100644 index 000000000..71becc7d4 --- /dev/null +++ b/lab6/solution/Test.java @@ -0,0 +1,70 @@ +package solution; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class Test { + public static final String MESSAGE_WELCOME = "Welcome to Starbucks!"; + public static final String MESSAGE_SEPERATOR = "==============================================="; + public static final String MESSAGE_SELECT = "Select functions:\n 1) Order\n 2) An order is ready\n 3) Check the queue\n 4) Exit"; + public static final String MESSAGE_SELECT_ONE = "Which drink you would like to order?"; + public static final String MESSAGE_SELECT_TWO = "Which order is ready?"; + public static final String MESSAGE_SELECT_THREE = "The following ids are in the queue:"; + public static final String MESSAGE_SELECT_FOUR = "Goodbye!~"; + public static final String MESSAGE_ERROR = "Please enter the number."; + + public static void main(String[] args) { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + // TODO: possible setup + Subject starbucks = new Subject(); + Adapter adapter = new Adapter(); + int id = 1; + + try { + System.out.println(MESSAGE_WELCOME); + loop: while(true) { + System.out.println(MESSAGE_SEPERATOR); + System.out.println(MESSAGE_SELECT); + String in = br.readLine(); + switch(in){ + case "1": + System.out.println(MESSAGE_SELECT_ONE); + String drink = br.readLine(); + // TODO: give an ordered id + // order is successful only if edit distance <= 3 + String beverage = adapter.getBeverage(drink); + if ( beverage != null ) { + Observer customer = new Observer(id++); + starbucks.register(customer); + customer.subscribe(starbucks); + System.out.println(String.format("%s is ordered and your order id is %d", beverage, customer.getID())); //success + } else { + System.out.println(String.format("%s not found.", drink)); //fail + } + break; + case "2": + System.out.println(MESSAGE_SELECT_TWO); + String order = br.readLine(); + // TODO: act appropriately according to your design + starbucks.setMessage(order); + break; + case "3": + System.out.println(MESSAGE_SELECT_THREE); + // print all id in the queue + starbucks.getQueue().forEach(o -> System.out.println(o.getID())); + break; + case "4": + break loop; + default: + System.out.println(MESSAGE_ERROR); + } + } + + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/lab6/solution/WagnerFischer.java b/lab6/solution/WagnerFischer.java new file mode 100644 index 000000000..f00b8b76c --- /dev/null +++ b/lab6/solution/WagnerFischer.java @@ -0,0 +1,45 @@ +package solution; +public class WagnerFischer { + private char[] s1; + private char[] s2; + + public WagnerFischer(String s1, String s2) { + this.s1 = s1.toLowerCase().toCharArray(); + this.s2 = s2.toLowerCase().toCharArray(); + } + + private int min(int a, int b, int c) { + return Math.min(a, Math.min(b, c)); + } + + /** + * Using Dynamic Programming, the Wagner-Fischer algorithm is able to + * calculate the edit distance between two strings. + * @return edit distance between s1 and s2 + */ + public int getDistance() { + int[][] dp = new int[s1.length + 1][s2.length + 1]; + for (int i = 0; i <= s1.length; dp[i][0] = i++); + for (int j = 0; j <= s2.length; dp[0][j] = j++); + + for (int i = 1; i <= s1.length; i++) { + for (int j = 1; j <= s2.length; j++) { + if (s1[i - 1] == s2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, + dp[i - 1][j - 1] + 1); + } + } + } + return dp[s1.length][s2.length]; + } + + public static void main(String[] args) { + WagnerFischer wf = new WagnerFischer("Caffe Mocha", "coffee moka"); + System.out.println(wf.getDistance()); + wf = new WagnerFischer("Frappuccino", "fappiccino"); + System.out.println(wf.getDistance()); + } + +} From 256ce8606eced75163f87ee9e3352e40c30457a9 Mon Sep 17 00:00:00 2001 From: gzwongkk Date: Fri, 27 Oct 2017 17:10:18 +0800 Subject: [PATCH 2/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4aa66c46b..97fa3b45d 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ You need to have some backgrounds on Java/Database/git in order to complete the | | 5 | No lab at week 5 | | | 4 | 6 | [UML](./lab_UML.pdf) | [Solution](./uml_lab_sample_answer.pdf) | | | 7 | No lab at week 7 | | -| 5 | 8 | [Design Pattern](./lab6/lab_design_pattern.pdf) | +| 5 | 8 | [Design Pattern](./lab5/lab_design_pattern.pdf) |[Solution](./lab5/solution/)| | 6 | 9 | [Refactoring](./refactoring-lab/README.md) | From 41a95f1c32820f53d9d2ad107bd91c7769151922 Mon Sep 17 00:00:00 2001 From: gzwongkk Date: Fri, 27 Oct 2017 17:12:38 +0800 Subject: [PATCH 3/5] Rename lab folder --- Lab5/temp | 1 + 1 file changed, 1 insertion(+) create mode 100644 Lab5/temp diff --git a/Lab5/temp b/Lab5/temp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Lab5/temp @@ -0,0 +1 @@ + From 884e267e1b703605df32a6d0d1246f0068182e91 Mon Sep 17 00:00:00 2001 From: gzwongkk Date: Fri, 27 Oct 2017 17:33:07 +0800 Subject: [PATCH 4/5] Update lab5 materials --- {lab6 => Lab5}/lab_design_pattern.pdf | Bin {lab6 => Lab5/skeleton}/Adapter.java | 0 {lab6 => Lab5/skeleton}/Observer.java | 0 {lab6 => Lab5/skeleton}/Subject.java | 0 {lab6 => Lab5/skeleton}/Test.java | 0 {lab6 => Lab5/skeleton}/WagnerFischer.java | 0 {lab6 => Lab5}/solution/Adapter.java | 0 {lab6 => Lab5}/solution/Observer.java | 0 {lab6 => Lab5}/solution/Subject.java | 0 {lab6 => Lab5}/solution/Test.java | 0 {lab6 => Lab5}/solution/WagnerFischer.java | 0 Lab5/temp | 1 - 12 files changed, 1 deletion(-) rename {lab6 => Lab5}/lab_design_pattern.pdf (100%) rename {lab6 => Lab5/skeleton}/Adapter.java (100%) rename {lab6 => Lab5/skeleton}/Observer.java (100%) rename {lab6 => Lab5/skeleton}/Subject.java (100%) rename {lab6 => Lab5/skeleton}/Test.java (100%) rename {lab6 => Lab5/skeleton}/WagnerFischer.java (100%) rename {lab6 => Lab5}/solution/Adapter.java (100%) rename {lab6 => Lab5}/solution/Observer.java (100%) rename {lab6 => Lab5}/solution/Subject.java (100%) rename {lab6 => Lab5}/solution/Test.java (100%) rename {lab6 => Lab5}/solution/WagnerFischer.java (100%) delete mode 100644 Lab5/temp diff --git a/lab6/lab_design_pattern.pdf b/Lab5/lab_design_pattern.pdf similarity index 100% rename from lab6/lab_design_pattern.pdf rename to Lab5/lab_design_pattern.pdf diff --git a/lab6/Adapter.java b/Lab5/skeleton/Adapter.java similarity index 100% rename from lab6/Adapter.java rename to Lab5/skeleton/Adapter.java diff --git a/lab6/Observer.java b/Lab5/skeleton/Observer.java similarity index 100% rename from lab6/Observer.java rename to Lab5/skeleton/Observer.java diff --git a/lab6/Subject.java b/Lab5/skeleton/Subject.java similarity index 100% rename from lab6/Subject.java rename to Lab5/skeleton/Subject.java diff --git a/lab6/Test.java b/Lab5/skeleton/Test.java similarity index 100% rename from lab6/Test.java rename to Lab5/skeleton/Test.java diff --git a/lab6/WagnerFischer.java b/Lab5/skeleton/WagnerFischer.java similarity index 100% rename from lab6/WagnerFischer.java rename to Lab5/skeleton/WagnerFischer.java diff --git a/lab6/solution/Adapter.java b/Lab5/solution/Adapter.java similarity index 100% rename from lab6/solution/Adapter.java rename to Lab5/solution/Adapter.java diff --git a/lab6/solution/Observer.java b/Lab5/solution/Observer.java similarity index 100% rename from lab6/solution/Observer.java rename to Lab5/solution/Observer.java diff --git a/lab6/solution/Subject.java b/Lab5/solution/Subject.java similarity index 100% rename from lab6/solution/Subject.java rename to Lab5/solution/Subject.java diff --git a/lab6/solution/Test.java b/Lab5/solution/Test.java similarity index 100% rename from lab6/solution/Test.java rename to Lab5/solution/Test.java diff --git a/lab6/solution/WagnerFischer.java b/Lab5/solution/WagnerFischer.java similarity index 100% rename from lab6/solution/WagnerFischer.java rename to Lab5/solution/WagnerFischer.java diff --git a/Lab5/temp b/Lab5/temp deleted file mode 100644 index 8b1378917..000000000 --- a/Lab5/temp +++ /dev/null @@ -1 +0,0 @@ - From 9a1d64763a8dcbe5e2f26f16b259571c19da4451 Mon Sep 17 00:00:00 2001 From: gzwongkk Date: Fri, 27 Oct 2017 17:36:38 +0800 Subject: [PATCH 5/5] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 97fa3b45d..b958f31cb 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ You need to have some backgrounds on Java/Database/git in order to complete the | | 5 | No lab at week 5 | | | 4 | 6 | [UML](./lab_UML.pdf) | [Solution](./uml_lab_sample_answer.pdf) | | | 7 | No lab at week 7 | | -| 5 | 8 | [Design Pattern](./lab5/lab_design_pattern.pdf) |[Solution](./lab5/solution/)| +| 5 | 8 | [Design Pattern](./Lab5/lab_design_pattern.pdf) |[Solution](./Lab5/solution/)| | 6 | 9 | [Refactoring](./refactoring-lab/README.md) |