From 8b048b5812e3e73e4129276ede427fd97458b592 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Wed, 10 May 2023 17:13:00 +0900 Subject: [PATCH 01/10] =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=ED=8B=80=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/Main.java | 8 + me/smartstore/SmartStoreApp.java | 60 +++++++ me/smartstore/arrays/Collections.java | 16 ++ me/smartstore/arrays/DArray.java | 147 ++++++++++++++++++ me/smartstore/customer/Customer.java | 83 ++++++++++ me/smartstore/customer/Customers.java | 25 +++ .../exception/ArrayEmptyException.java | 14 ++ .../exception/ElementNotFoundException.java | 22 +++ .../exception/EmptyArrayException.java | 22 +++ .../exception/InputEmptyException.java | 15 ++ .../exception/InputEndException.java | 13 ++ .../exception/InputFormatException.java | 13 ++ .../exception/InputRangeException.java | 14 ++ .../exception/InputTypeException.java | 14 ++ .../exception/NullArgumentException.java | 22 +++ me/smartstore/group/Group.java | 53 +++++++ me/smartstore/group/GroupType.java | 19 +++ me/smartstore/group/Groups.java | 25 +++ me/smartstore/group/Parameter.java | 53 +++++++ me/smartstore/menu/CustomerMenu.java | 32 ++++ me/smartstore/menu/GroupMenu.java | 76 +++++++++ me/smartstore/menu/MainMenu.java | 34 ++++ me/smartstore/menu/Menu.java | 46 ++++++ me/smartstore/menu/SummaryMenu.java | 32 ++++ me/smartstore/util/Message.java | 13 ++ 25 files changed, 871 insertions(+) create mode 100644 me/smartstore/Main.java create mode 100644 me/smartstore/SmartStoreApp.java create mode 100644 me/smartstore/arrays/Collections.java create mode 100644 me/smartstore/arrays/DArray.java create mode 100644 me/smartstore/customer/Customer.java create mode 100644 me/smartstore/customer/Customers.java create mode 100644 me/smartstore/exception/ArrayEmptyException.java create mode 100644 me/smartstore/exception/ElementNotFoundException.java create mode 100644 me/smartstore/exception/EmptyArrayException.java create mode 100644 me/smartstore/exception/InputEmptyException.java create mode 100644 me/smartstore/exception/InputEndException.java create mode 100644 me/smartstore/exception/InputFormatException.java create mode 100644 me/smartstore/exception/InputRangeException.java create mode 100644 me/smartstore/exception/InputTypeException.java create mode 100644 me/smartstore/exception/NullArgumentException.java create mode 100644 me/smartstore/group/Group.java create mode 100644 me/smartstore/group/GroupType.java create mode 100644 me/smartstore/group/Groups.java create mode 100644 me/smartstore/group/Parameter.java create mode 100644 me/smartstore/menu/CustomerMenu.java create mode 100644 me/smartstore/menu/GroupMenu.java create mode 100644 me/smartstore/menu/MainMenu.java create mode 100644 me/smartstore/menu/Menu.java create mode 100644 me/smartstore/menu/SummaryMenu.java create mode 100644 me/smartstore/util/Message.java diff --git a/me/smartstore/Main.java b/me/smartstore/Main.java new file mode 100644 index 00000000..549a8040 --- /dev/null +++ b/me/smartstore/Main.java @@ -0,0 +1,8 @@ +package me.smartstore; + +public class Main { + public static void main(String[] args) { + SmartStoreApp.getInstance().test().run(); // function chaining + // SmartStoreApp.getInstance().run(); + } +} diff --git a/me/smartstore/SmartStoreApp.java b/me/smartstore/SmartStoreApp.java new file mode 100644 index 00000000..dfa9b523 --- /dev/null +++ b/me/smartstore/SmartStoreApp.java @@ -0,0 +1,60 @@ +package me.smartstore; + + +import me.smartstore.customer.Customer; +import me.smartstore.customer.Customers; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; +import me.smartstore.group.Groups; +import me.smartstore.group.Parameter; +import me.smartstore.menu.MainMenu; + +public class SmartStoreApp { + private final Groups allGroups = Groups.getInstance(); + private final Customers allCustomers = Customers.getInstance(); + private final MainMenu mainMenu = MainMenu.getInstance(); + private static SmartStoreApp smartStoreApp; + + public static SmartStoreApp getInstance(){ + if(smartStoreApp == null){ + smartStoreApp = new SmartStoreApp(); + } + return smartStoreApp; + } + private SmartStoreApp(){} + public void details(){ + System.out.println("\n\n==========================================="); + System.out.println(" Title : SmartStore Customer Classification"); + System.out.println(" Release Date : 23.04.27"); + System.out.println(" Copyright 2023 Eunbin All rights reserved."); + System.out.println("===========================================\n"); + } + public SmartStoreApp test(){ + allGroups.add(new Group(new Parameter(10, 100000), GroupType.GENERAL)); + allGroups.add(new Group(new Parameter(20, 200000), GroupType.VIP)); + allGroups.add(new Group(new Parameter(30, 300000), GroupType.VVIP)); + + + for (int i = 0; i < 26; i++) { + allCustomers.add(new Customer( + Character.toString( + (char) ('a' + i)), + (char) ('a' + i) + "123", + ((int) (Math.random() * 5) + 1) * 10, + ((int) (Math.random() * 5) + 1) * 100000)); + } + + System.out.println("allCustomers = " + allCustomers); + System.out.println("allGroups = " + allGroups); + + // @TODO: refresh do not implemented yet. + allCustomers.refresh(allGroups); + + return this; // smartStoreApp + } + public void run() { + details(); + mainMenu.manage(); + } + +} \ No newline at end of file diff --git a/me/smartstore/arrays/Collections.java b/me/smartstore/arrays/Collections.java new file mode 100644 index 00000000..c251b096 --- /dev/null +++ b/me/smartstore/arrays/Collections.java @@ -0,0 +1,16 @@ +package me.smartstore.arrays; + +public interface Collections { + + int size(); + T get(int index); + void set(int index, T object); + int indexOf(T object); + void add(T object); + void add(int index, T object); + T pop(); + T pop(int index); + T pop(T object); + + +} diff --git a/me/smartstore/arrays/DArray.java b/me/smartstore/arrays/DArray.java new file mode 100644 index 00000000..09b88582 --- /dev/null +++ b/me/smartstore/arrays/DArray.java @@ -0,0 +1,147 @@ +package me.smartstore.arrays; + +import me.smartstore.exception.ElementNotFoundException; +import me.smartstore.exception.EmptyArrayException; +import me.smartstore.exception.NullArgumentException; + +public class DArray implements Collections { + protected static final int DEFAULT = 10; + + protected T[] arrays; + protected int size; + protected int capacity; + + public DArray() throws ClassCastException { + arrays = (T[]) new Object[DEFAULT]; + capacity = DEFAULT; + } + + public DArray(int initial) throws ClassCastException { + arrays = (T[]) new Object[initial]; + capacity = initial; + } + + public DArray(T[] arrays) { + this.arrays = arrays; + capacity = arrays.length; + size = arrays.length; + } + + ///////////////////////////////////////// + // add, set, get, pop, indexOf, size, capacity (for dynamic-sized array) + + @Override + public int size() { + return size; + } + + // 배열에 얼마나 capacity 남아있는지 외부에 알려줄 필요가 없기 때문에 으로 정의 + protected int capacity() { + return capacity; + } + + @Override + public T get(int index) throws IndexOutOfBoundsException { + if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); + return arrays[index]; + } + + /** + * @param: ... + * @return: ... + * @throws: IndexOutOfBoundsException + * @throws: NullArgumentException + * */ + @Override + public void set(int index, T object) throws IndexOutOfBoundsException, NullArgumentException { + if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); + if (object == null) throw new NullArgumentException(); + + arrays[index] = object; + } + + @Override + public int indexOf(T object) throws NullArgumentException, ElementNotFoundException { + if (object == null) throw new NullArgumentException(); // not found (instead of throwing exception) + + for (int i = 0; i < size; i++) { + if (arrays[i] == null) continue; + if (arrays[i].equals(object)) return i; + } + throw new ElementNotFoundException(); // not found + } + + // 배열의 cap이 부족한 경우 + @Override + public void add(T object) throws NullArgumentException { + if (object == null) throw new NullArgumentException(); // if argument is null, do not add null value in array + + if (size < capacity) { + arrays[size] = object; + size++; + } else { + grow(); + add(object); + } + } + + @Override + public void add(int index, T object) throws IndexOutOfBoundsException, NullArgumentException { + if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); + if (object == null) throw new NullArgumentException(); + + if (size < capacity) { + for (int i = size-1; i >= index ; i--) { + arrays[i+1] = arrays[i]; + } + arrays[index] = object; + size++; + } else { + grow(); + add(index, object); + } + } + + @Override + public T pop() { + return pop(size-1); + } + + @Override + public T pop(int index) throws IndexOutOfBoundsException { + if (size == 0) throw new EmptyArrayException(); + if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); + + T popElement = arrays[index]; + arrays[index] = null; // 삭제됨을 명시적으로 표현 + + for (int i = index+1; i < size; i++) { + arrays[i-1] = arrays[i]; + } + arrays[size-1] = null; + size--; + return popElement; + } + + @Override + public T pop(T object) { + return pop(indexOf(object)); + } + + protected void grow() { + capacity *= 2; // doubling + arrays = java.util.Arrays.copyOf(arrays, capacity); + + // size는 그대로 + } + + @Override + public String toString() { + String toStr = ""; + for (int i = 0; i < size; i++) { + toStr += (arrays[i] + "\n"); + } + return toStr; + } +} + diff --git a/me/smartstore/customer/Customer.java b/me/smartstore/customer/Customer.java new file mode 100644 index 00000000..039d2d5e --- /dev/null +++ b/me/smartstore/customer/Customer.java @@ -0,0 +1,83 @@ +package me.smartstore.customer; + +import me.smartstore.group.Group; + +import java.util.Objects; + +public class Customer { + private String cName; + private String cId; + private Integer totalTime; + private Integer totalPay; + private Group group; + //refresh 함수가 호출되는 경우 -> 분류기준이 바뀔때, 새로운 고객이 들어올때 + + public Customer(){ + + } + public Customer(String cName, String cId) { + this.cName = cName; + this.cId = cId; + } + + public Customer(String cName, String cId, Integer totalTime, Integer totalPay) { + this.cName = cName; + this.cId = cId; + this.totalTime = totalTime; + this.totalPay = totalPay; + } + + public String getcName() { + return cName; + } + + public void setcName(String cName) { + this.cName = cName; + } + + public String getcId() { + return cId; + } + + public void setcId(String cId) { + this.cId = cId; + } + + public Integer getTotalTime() { + return totalTime; + } + + public void setTotalTime(Integer totalTime) { + this.totalTime = totalTime; + } + + public Integer getTotalPay() { + return totalPay; + } + + public void setTotalPay(Integer totalPay) { + this.totalPay = totalPay; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Customer customer = (Customer) o; + return Objects.equals(cId, customer.cId); + } + + @Override + public int hashCode() { + return Objects.hash(cId); + } + + @Override + public String toString() { + return "Customer{" + + "cName='" + cName + '\'' + + ", cId='" + cId + '\'' + + ", totalTime=" + totalTime + + ", totalPay=" + totalPay + + '}'; + } +} \ No newline at end of file diff --git a/me/smartstore/customer/Customers.java b/me/smartstore/customer/Customers.java new file mode 100644 index 00000000..c2522ac7 --- /dev/null +++ b/me/smartstore/customer/Customers.java @@ -0,0 +1,25 @@ +package me.smartstore.customer; + +import me.smartstore.arrays.DArray; +import me.smartstore.group.Groups; + +public class Customers extends DArray { + private static Customers allCustomers; + + public static Customers getInstance() { + if (allCustomers == null) { + allCustomers = new Customers(); + } + return allCustomers; + } + + private Customers() {} + + // refresh 함수가 호출되는 경우 + // 1. 분류기준 바뀔 때 + // 2. 새로운 고객이 들어올 때 + public void refresh(Groups groups) { + + } + +} \ No newline at end of file diff --git a/me/smartstore/exception/ArrayEmptyException.java b/me/smartstore/exception/ArrayEmptyException.java new file mode 100644 index 00000000..737945ac --- /dev/null +++ b/me/smartstore/exception/ArrayEmptyException.java @@ -0,0 +1,14 @@ +package me.smartstore.exception; + +import me.smartstore.util.Message; + +public class ArrayEmptyException extends RuntimeException { + + public ArrayEmptyException() { + super(Message.ERR_MSG_INVALID_ARR_EMPTY); + } + + public ArrayEmptyException(String message) { + super(message); + } +} diff --git a/me/smartstore/exception/ElementNotFoundException.java b/me/smartstore/exception/ElementNotFoundException.java new file mode 100644 index 00000000..6e934998 --- /dev/null +++ b/me/smartstore/exception/ElementNotFoundException.java @@ -0,0 +1,22 @@ +package me.smartstore.exception; + +public class ElementNotFoundException extends RuntimeException { + public ElementNotFoundException() { + } + + public ElementNotFoundException(String message) { + super(message); + } + + public ElementNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public ElementNotFoundException(Throwable cause) { + super(cause); + } + + public ElementNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/me/smartstore/exception/EmptyArrayException.java b/me/smartstore/exception/EmptyArrayException.java new file mode 100644 index 00000000..b19aeac3 --- /dev/null +++ b/me/smartstore/exception/EmptyArrayException.java @@ -0,0 +1,22 @@ +package me.smartstore.exception; + +public class EmptyArrayException extends RuntimeException { + public EmptyArrayException() { + } + + public EmptyArrayException(String message) { + super(message); + } + + public EmptyArrayException(String message, Throwable cause) { + super(message, cause); + } + + public EmptyArrayException(Throwable cause) { + super(cause); + } + + public EmptyArrayException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/me/smartstore/exception/InputEmptyException.java b/me/smartstore/exception/InputEmptyException.java new file mode 100644 index 00000000..93163bc6 --- /dev/null +++ b/me/smartstore/exception/InputEmptyException.java @@ -0,0 +1,15 @@ +package me.smartstore.exception; + + +import me.smartstore.util.Message; + +public class InputEmptyException extends RuntimeException { + + public InputEmptyException() { + super(Message.ERR_MSG_INVALID_INPUT_EMPTY); + } + + public InputEmptyException(String message) { + super(message); + } +} diff --git a/me/smartstore/exception/InputEndException.java b/me/smartstore/exception/InputEndException.java new file mode 100644 index 00000000..ffba020a --- /dev/null +++ b/me/smartstore/exception/InputEndException.java @@ -0,0 +1,13 @@ +package me.smartstore.exception; + +import me.smartstore.util.Message; + +public class InputEndException extends RuntimeException { + public InputEndException() { + super(Message.ERR_MSG_INPUT_END); + } + + public InputEndException(String message) { + super(message); + } +} diff --git a/me/smartstore/exception/InputFormatException.java b/me/smartstore/exception/InputFormatException.java new file mode 100644 index 00000000..edc44e44 --- /dev/null +++ b/me/smartstore/exception/InputFormatException.java @@ -0,0 +1,13 @@ +package me.smartstore.exception; + +import me.smartstore.util.Message; + +public class InputFormatException extends RuntimeException { + public InputFormatException() { + super(Message.ERR_MSG_INVALID_INPUT_FORMAT); + } + + public InputFormatException(String message) { + super(message); + } +} diff --git a/me/smartstore/exception/InputRangeException.java b/me/smartstore/exception/InputRangeException.java new file mode 100644 index 00000000..fb2c76df --- /dev/null +++ b/me/smartstore/exception/InputRangeException.java @@ -0,0 +1,14 @@ +package me.smartstore.exception; + + +import me.smartstore.util.Message; + +public class InputRangeException extends RuntimeException { + public InputRangeException() { + super(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + + public InputRangeException(String message) { + super(message); + } +} diff --git a/me/smartstore/exception/InputTypeException.java b/me/smartstore/exception/InputTypeException.java new file mode 100644 index 00000000..d321992f --- /dev/null +++ b/me/smartstore/exception/InputTypeException.java @@ -0,0 +1,14 @@ +package me.smartstore.exception; + + +import me.smartstore.util.Message; + +public class InputTypeException extends RuntimeException { + public InputTypeException() { + super(Message.ERR_MSG_INVALID_INPUT_TYPE); + } + + public InputTypeException(String message) { + super(message); + } +} diff --git a/me/smartstore/exception/NullArgumentException.java b/me/smartstore/exception/NullArgumentException.java new file mode 100644 index 00000000..e2a8531d --- /dev/null +++ b/me/smartstore/exception/NullArgumentException.java @@ -0,0 +1,22 @@ +package me.smartstore.exception; + +public class NullArgumentException extends RuntimeException { + public NullArgumentException() { + } + + public NullArgumentException(String message) { + super(message); + } + + public NullArgumentException(String message, Throwable cause) { + super(message, cause); + } + + public NullArgumentException(Throwable cause) { + super(cause); + } + + public NullArgumentException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/me/smartstore/group/Group.java b/me/smartstore/group/Group.java new file mode 100644 index 00000000..96bd6fbb --- /dev/null +++ b/me/smartstore/group/Group.java @@ -0,0 +1,53 @@ +package me.smartstore.group; + +import java.util.Objects; + +public class Group { + private Parameter parameter; //분류기준 + private GroupType groupType; //분류한 그룹 타입 + + public Group() { + } + + public Group(Parameter parameter, GroupType groupType) { + this.parameter = parameter; + this.groupType = groupType; + } + + public Parameter getParameter() { + return parameter; + } + + public void setParameter(Parameter parameter) { + this.parameter = parameter; + } + + public GroupType getGroupType() { + return groupType; + } + + public void setGroupType(GroupType groupType) { + this.groupType = groupType; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Group group = (Group) o; + return Objects.equals(parameter, group.parameter) && groupType == group.groupType; + } + + @Override + public int hashCode() { + return Objects.hash(parameter, groupType); + } + + @Override + public String toString() { + return "Group{" + + "parameter=" + parameter + + ", groupType=" + groupType + + '}'; + } +} \ No newline at end of file diff --git a/me/smartstore/group/GroupType.java b/me/smartstore/group/GroupType.java new file mode 100644 index 00000000..0c437e4a --- /dev/null +++ b/me/smartstore/group/GroupType.java @@ -0,0 +1,19 @@ +package me.smartstore.group; + +public enum GroupType { + N("해당없음"), G("일반고객"), V("우수고객"), VV("최우수고객"), + NONE("해당없음"), GENERAL("일반고객"), VIP("우수고객"), VVIP("최우수고객"); + String groupType = ""; + GroupType(String groupType) { + this.groupType = groupType; + } + + + public GroupType replaceFullName(){ + if(this == N) return NONE; + else if (this == G) return GENERAL; + else if (this == V) return VIP; + else if (this == VV) return VVIP; + return this; + } +} \ No newline at end of file diff --git a/me/smartstore/group/Groups.java b/me/smartstore/group/Groups.java new file mode 100644 index 00000000..2b465b44 --- /dev/null +++ b/me/smartstore/group/Groups.java @@ -0,0 +1,25 @@ +package me.smartstore.group; + +import me.smartstore.arrays.DArray; + +public class Groups extends DArray { + private static Groups allGroups; + + public static Groups getInstance(){ + if(allGroups == null){ + allGroups = new Groups(); + } + return allGroups; + } + private Groups(){} + + public Group find(GroupType groupType){ + for (int i = 0; i < allGroups.size; i++) { + if (allGroups.get(i).getGroupType() == groupType) { + return allGroups.get(i); + } + } + return null; + } + +} \ No newline at end of file diff --git a/me/smartstore/group/Parameter.java b/me/smartstore/group/Parameter.java new file mode 100644 index 00000000..7f59d14f --- /dev/null +++ b/me/smartstore/group/Parameter.java @@ -0,0 +1,53 @@ +package me.smartstore.group; + +import java.util.Objects; + +public class Parameter { + private Integer minTime; + private Integer minPay; + + public Parameter() { + } + + public Parameter(Integer minTime, Integer minPay) { + this.minTime = minTime; + this.minPay = minPay; + } + + public Integer getMinTime() { + return minTime; + } + + public void setMinTime(Integer minTime) { + this.minTime = minTime; + } + + public Integer getMinPay() { + return minPay; + } + + public void setMinPay(Integer minPay) { + this.minPay = minPay; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Parameter parameter = (Parameter) o; + return Objects.equals(minTime, parameter.minTime) && Objects.equals(minPay, parameter.minPay); + } + + @Override + public int hashCode() { + return Objects.hash(minTime, minPay); + } + + @Override + public String toString() { + return "Parameter{" + + "minTime=" + minTime + + ", minPay=" + minPay + + '}'; + } +} \ No newline at end of file diff --git a/me/smartstore/menu/CustomerMenu.java b/me/smartstore/menu/CustomerMenu.java new file mode 100644 index 00000000..532ad22c --- /dev/null +++ b/me/smartstore/menu/CustomerMenu.java @@ -0,0 +1,32 @@ +package me.smartstore.menu; + +public class CustomerMenu implements Menu{ + private static CustomerMenu customerMenu; + + public static CustomerMenu getInstance(){ + if(customerMenu == null){ + customerMenu = new CustomerMenu(); + } + return customerMenu; + } + private CustomerMenu(){} + + @Override + public void manage() { + while (true) { + int choice = chooseMenu(new String[]{ + "Add Customer", + "View Customer", + "Update Customer", + "Delete Customer", + "Back" + }); + if(choice == 1) {}//addCustomer(); + else if(choice == 2) {}//viewCustomer(); + else if(choice == 3) {}//updateCustomer(); + else if(choice == 4) {}//deleteCustomer(); + else break; + } + + } +} \ No newline at end of file diff --git a/me/smartstore/menu/GroupMenu.java b/me/smartstore/menu/GroupMenu.java new file mode 100644 index 00000000..dc58b529 --- /dev/null +++ b/me/smartstore/menu/GroupMenu.java @@ -0,0 +1,76 @@ +package me.smartstore.menu; + +import me.smartstore.customer.Customers; +import me.smartstore.exception.InputEndException; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; +import me.smartstore.group.Groups; +import me.smartstore.group.Parameter; +import me.smartstore.util.Message; + +public class GroupMenu implements Menu { + private static GroupMenu groupMenu; + private final Customers allCustomers = Customers.getInstance(); + private final Groups allGroups = Groups.getInstance(); + + public static GroupMenu getInstance(){ + if(groupMenu == null){ + groupMenu = new GroupMenu(); + } + return groupMenu; + } + private GroupMenu(){} + + @Override + public void manage() { + while (true) { + int choice = chooseMenu(new String[]{ + "Set Parameter", + "View Parameter", + "Update Parameter", + "Back" + }); + if(choice == 1) setParameter(); + else if(choice == 2) {}//viewParameter(); + else if(choice == 3) {}//updateParameter(); + else break; + } + } + public GroupType chooseGroup(){ + while(true){ + try { + System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); + String choice = nextLine(Message.END_MSG); + // group (str) -> GroupType (enum) + // "VIP" -> GroupType.VIP + GroupType groupType = GroupType.valueOf(choice).replaceFullName(); // String -> enum + return groupType; + }catch (InputEndException e){ + System.out.println(Message.ERR_MSG_INPUT_END); + return null; + } catch (IllegalArgumentException e){ + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } + + public void setParameter(){ + while (true){ + GroupType groupType = chooseGroup(); + + //GroupType에 해당하는 group객체를 찾아야함 + Group group = allGroups.find(groupType); + if (group != null && group.getParameter() != null) { // group.getParameter()이 null이 아니면 이미 초기화됨 + System.out.println("\n" + group.getGroupType() + " group already exists."); + System.out.println("\n" + group); + } else { + Parameter parameter = new Parameter(); + // time, pay 사용자 입력받은 후, 설정 필요 + + group.setParameter(parameter); + allCustomers.refresh(allGroups); // 파라미터가 변경되었거나 추가되는 경우, 고객 분류를 다시 해야함 + } + } + } + +} \ No newline at end of file diff --git a/me/smartstore/menu/MainMenu.java b/me/smartstore/menu/MainMenu.java new file mode 100644 index 00000000..a252b438 --- /dev/null +++ b/me/smartstore/menu/MainMenu.java @@ -0,0 +1,34 @@ +package me.smartstore.menu; + +public class MainMenu implements Menu{ + private final CustomerMenu customerMenu = CustomerMenu.getInstance(); + private final GroupMenu groupMenu = GroupMenu.getInstance(); + private final SummaryMenu summaryMenu = SummaryMenu.getInstance(); + private static MainMenu mainMenu; + + public static MainMenu getInstance(){ + if(mainMenu == null){ + mainMenu = new MainMenu(); + } + return mainMenu; + } + private MainMenu(){} + + @Override + public void manage() { + while(true){ //프로그램 실행 while + int choice = mainMenu.chooseMenu(new String[] { + "Parameter", + "Customer Data", + "Classification Summary", + "Quit" + }); + if(choice == 1) groupMenu.manage(); + else if(choice == 2) customerMenu.manage(); + else if(choice == 3) summaryMenu.manage(); + else {System.out.println("Program Finish"); break;} + } + } + + +} \ No newline at end of file diff --git a/me/smartstore/menu/Menu.java b/me/smartstore/menu/Menu.java new file mode 100644 index 00000000..15ac3171 --- /dev/null +++ b/me/smartstore/menu/Menu.java @@ -0,0 +1,46 @@ +package me.smartstore.menu; + +import me.smartstore.exception.InputEndException; +import me.smartstore.exception.InputRangeException; +import me.smartstore.util.Message; + +import java.util.Scanner; + +public interface Menu { + public Scanner scanner = new Scanner(System.in); + + default String nextLine(){ //String + return scanner.nextLine().toUpperCase(); //대소문자 구분 없애기 위해 + } + default String nextLine(String end) { + System.out.println("** Press 'end', if you want to exit! **"); + String str = scanner.nextLine().toUpperCase(); + if (str.equals(end)) throw new InputEndException(); + return str; + } + /**public String nextLine(){ //Integer + String str = scanner.nextLine().toUpperCase(); //대소문자 구분 없애기 위해 + return str; + }*/ + default int chooseMenu(String[] menus){ + while(true) { //예외 복구 while + try { + System.out.println("==============================="); + for (int i = 0; i < menus.length; i++) { + System.out.printf(" %d. %s\n", i + 1, menus[i]); + } + System.out.println("==============================="); + System.out.print("Choose One: "); + int choice = Integer.parseInt(nextLine()); + if (choice >= 1 && choice <= menus.length) return choice; + throw new InputRangeException(); // choice 가 범위에 벗어남 + } catch (NumberFormatException e){ + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + } catch (InputRangeException e){ + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } + void manage(); //각 서브메뉴들을 관리하는 함수 + +} \ No newline at end of file diff --git a/me/smartstore/menu/SummaryMenu.java b/me/smartstore/menu/SummaryMenu.java new file mode 100644 index 00000000..f72c50fa --- /dev/null +++ b/me/smartstore/menu/SummaryMenu.java @@ -0,0 +1,32 @@ +package me.smartstore.menu; + +public class SummaryMenu implements Menu { + private static SummaryMenu summaryMenu; + + public static SummaryMenu getInstance(){ + if(summaryMenu == null){ + summaryMenu = new SummaryMenu(); + } + return summaryMenu; + } + private SummaryMenu(){} + + @Override + public void manage() { + while (true) { //서브 메뉴 페이지를 유지하기 위한 while + int choice = chooseMenu(new String[]{ + "Summary", + "Summary (Sorted By Name)", + "Summary (Sorted By Spent Time)", + "Summary (Sorted By Total Payment)", + "Back" + }); + if(choice == 1) {}//summary(); + else if(choice == 2) {}//sortedByName(); + else if(choice == 3) {}//sortedBySpentTime(); + else if(choice == 4) {}//sortedByTotalPayment(); + else break; + } + + } +} \ No newline at end of file diff --git a/me/smartstore/util/Message.java b/me/smartstore/util/Message.java new file mode 100644 index 00000000..1c67d21e --- /dev/null +++ b/me/smartstore/util/Message.java @@ -0,0 +1,13 @@ +package me.smartstore.util; + +public interface Message { + String ERR_MSG_INVALID_ARR_EMPTY = "No Customers. Please input one first."; + String ERR_MSG_NULL_ARR_ELEMENT = "Elements in Array has null. Array can't be sorted."; + String ERR_MSG_INVALID_INPUT_NULL = "Null Input. Please input something."; + String ERR_MSG_INVALID_INPUT_EMPTY = "Empty Input. Please input something."; + String ERR_MSG_INVALID_INPUT_RANGE = "Invalid Input. Please try again."; + String ERR_MSG_INVALID_INPUT_TYPE = "Invalid Type for Input. Please try again."; + String ERR_MSG_INVALID_INPUT_FORMAT = "Invalid Format for Input. Please try again."; + String ERR_MSG_INPUT_END = "END is pressed. Exit this menu."; + String END_MSG = "END"; +} From 8b7e0152de020e5355415506b02522a1d7d3d612 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Wed, 10 May 2023 17:50:06 +0900 Subject: [PATCH 02/10] =?UTF-8?q?GroupMenu=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/SmartStoreApp.java | 6 +- me/smartstore/customer/Customer.java | 9 ++ me/smartstore/customer/Customers.java | 26 +++++- me/smartstore/menu/GroupMenu.java | 126 +++++++++++++++++++++++--- 4 files changed, 149 insertions(+), 18 deletions(-) diff --git a/me/smartstore/SmartStoreApp.java b/me/smartstore/SmartStoreApp.java index dfa9b523..4b44af60 100644 --- a/me/smartstore/SmartStoreApp.java +++ b/me/smartstore/SmartStoreApp.java @@ -30,6 +30,7 @@ public void details(){ System.out.println("===========================================\n"); } public SmartStoreApp test(){ + allGroups.add(new Group(new Parameter(10, 100000), GroupType.GENERAL)); allGroups.add(new Group(new Parameter(20, 200000), GroupType.VIP)); allGroups.add(new Group(new Parameter(30, 300000), GroupType.VVIP)); @@ -48,9 +49,12 @@ public SmartStoreApp test(){ System.out.println("allGroups = " + allGroups); // @TODO: refresh do not implemented yet. - allCustomers.refresh(allGroups); + allCustomers.refresh(); + return this; // smartStoreApp + + } public void run() { details(); diff --git a/me/smartstore/customer/Customer.java b/me/smartstore/customer/Customer.java index 039d2d5e..2e9c6d51 100644 --- a/me/smartstore/customer/Customer.java +++ b/me/smartstore/customer/Customer.java @@ -58,6 +58,15 @@ public Integer getTotalPay() { public void setTotalPay(Integer totalPay) { this.totalPay = totalPay; } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/me/smartstore/customer/Customers.java b/me/smartstore/customer/Customers.java index c2522ac7..3faab26e 100644 --- a/me/smartstore/customer/Customers.java +++ b/me/smartstore/customer/Customers.java @@ -1,9 +1,12 @@ package me.smartstore.customer; import me.smartstore.arrays.DArray; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; import me.smartstore.group.Groups; public class Customers extends DArray { + private final Groups allGroups = Groups.getInstance(); private static Customers allCustomers; public static Customers getInstance() { @@ -18,8 +21,27 @@ private Customers() {} // refresh 함수가 호출되는 경우 // 1. 분류기준 바뀔 때 // 2. 새로운 고객이 들어올 때 - public void refresh(Groups groups) { - + public void refresh() { + for (int i = 0; i < allCustomers.size(); i++) { + Customer customer = allCustomers.get(i); + Group group = findGroup(customer.getTotalTime(), customer.getTotalPay()); + customer.setGroup(group); + } } + public Group findGroup(int totalTime, int totalPay){ + try { + if(totalTime >= allGroups.find(GroupType.VVIP).getParameter().getMinTime() && totalPay>=allGroups.find(GroupType.VVIP).getParameter().getMinPay()){ + return allGroups.find(GroupType.VVIP); + } else if (totalTime >= allGroups.find(GroupType.VIP).getParameter().getMinTime() && totalPay>=allGroups.find(GroupType.VIP).getParameter().getMinPay()) { + return allGroups.find(GroupType.VIP); + } else if (totalTime >= allGroups.find(GroupType.GENERAL).getParameter().getMinTime() && totalPay>=allGroups.find(GroupType.GENERAL).getParameter().getMinPay()) { + return allGroups.find(GroupType.GENERAL); + } else{ + return allGroups.find(GroupType.NONE); + } + } catch (NullPointerException e){ + return null; + } + } } \ No newline at end of file diff --git a/me/smartstore/menu/GroupMenu.java b/me/smartstore/menu/GroupMenu.java index dc58b529..461b4523 100644 --- a/me/smartstore/menu/GroupMenu.java +++ b/me/smartstore/menu/GroupMenu.java @@ -13,13 +13,15 @@ public class GroupMenu implements Menu { private final Customers allCustomers = Customers.getInstance(); private final Groups allGroups = Groups.getInstance(); - public static GroupMenu getInstance(){ - if(groupMenu == null){ + public static GroupMenu getInstance() { + if (groupMenu == null) { groupMenu = new GroupMenu(); } return groupMenu; } - private GroupMenu(){} + + private GroupMenu() { + } @Override public void manage() { @@ -30,14 +32,15 @@ public void manage() { "Update Parameter", "Back" }); - if(choice == 1) setParameter(); - else if(choice == 2) {}//viewParameter(); - else if(choice == 3) {}//updateParameter(); + if (choice == 1) setParameter(); + else if (choice == 2) viewParameter(); + else if (choice == 3) updateParameter(); else break; } } - public GroupType chooseGroup(){ - while(true){ + + public GroupType chooseGroup() { + while (true) { try { System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); String choice = nextLine(Message.END_MSG); @@ -45,17 +48,17 @@ public GroupType chooseGroup(){ // "VIP" -> GroupType.VIP GroupType groupType = GroupType.valueOf(choice).replaceFullName(); // String -> enum return groupType; - }catch (InputEndException e){ + } catch (InputEndException e) { System.out.println(Message.ERR_MSG_INPUT_END); return null; - } catch (IllegalArgumentException e){ + } catch (IllegalArgumentException e) { System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); } } } - public void setParameter(){ - while (true){ + public void setParameter() { + while (true) { GroupType groupType = chooseGroup(); //GroupType에 해당하는 group객체를 찾아야함 @@ -64,11 +67,104 @@ public void setParameter(){ System.out.println("\n" + group.getGroupType() + " group already exists."); System.out.println("\n" + group); } else { - Parameter parameter = new Parameter(); - // time, pay 사용자 입력받은 후, 설정 필요 + group = new Group(new Parameter(), groupType); + allGroups.add(group); + while (true) { + int choice = chooseMenu(new String[]{ + "Minimum Spent Time", + "Minimum Total Pay", + "Back"}); + if (choice == 1) { + setMinimumSpentTime(group); + continue; + } + if (choice == 2) { + setMinimumTotalPay(group); + continue; + } + if (choice == 3) + break; + } + allCustomers.refresh(); + } + } + } + public void setMinimumSpentTime(Group group) { + while (true) { + try { + System.out.printf("Input Minimum Spent Time:"); + String spentTime = nextLine(Message.END_MSG); + Parameter parameter = group.getParameter(); + parameter.setMinTime(Integer.parseInt(spentTime)); + group.setParameter(parameter); + System.out.println(group.getParameter()); + allCustomers.refresh(); + break; + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } + } + + } + + public void setMinimumTotalPay(Group group) { + while (true) { + try { + System.out.printf("Input Minimum Total Pay:"); + String totalPay = nextLine(Message.END_MSG); + Parameter parameter = group.getParameter(); + parameter.setMinPay(Integer.parseInt(totalPay)); group.setParameter(parameter); - allCustomers.refresh(allGroups); // 파라미터가 변경되었거나 추가되는 경우, 고객 분류를 다시 해야함 + System.out.println(group.getParameter()); + allCustomers.refresh(); + break; + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } + } + } + + + public void viewParameter() { + while (true) { + GroupType groupType = chooseGroup(); + if (groupType == null) { + break; + } + Group group = allGroups.find(groupType); + System.out.println(groupType); + System.out.println(group.getParameter()); + } + } + + + public void updateParameter() { + while (true) { + GroupType groupType = chooseGroup(); + if (groupType == null) { + break; + } + Group group = allGroups.find(groupType); + System.out.println(groupType); + System.out.println(group.getParameter()); + while (true) { + int choice = chooseMenu(new String[]{ + "Minimum Spent Time", + "Minimum Total Pay", + "Back"}); + if (choice == 1) { + setMinimumSpentTime(group); + continue; + } + if (choice == 2) { + setMinimumTotalPay(group); + continue; + } + if (choice == 3) + break; } } } From 54abcf0a554e1d63073ecc970ee55f3058c792bf Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Wed, 10 May 2023 19:07:19 +0900 Subject: [PATCH 03/10] =?UTF-8?q?GroupMenu=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20test=201.=20Set=20Par=20=EB=8F=99=EC=9E=91?= =?UTF-8?q?=EC=8B=9C=20=EB=B9=A0=EC=A0=B8=EB=82=98=EC=98=A4=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/menu/GroupMenu.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/me/smartstore/menu/GroupMenu.java b/me/smartstore/menu/GroupMenu.java index 461b4523..d8f3ae9c 100644 --- a/me/smartstore/menu/GroupMenu.java +++ b/me/smartstore/menu/GroupMenu.java @@ -8,7 +8,8 @@ import me.smartstore.group.Parameter; import me.smartstore.util.Message; -public class GroupMenu implements Menu { +public class GroupMenu implements Menu{ + private static GroupMenu groupMenu; private final Customers allCustomers = Customers.getInstance(); private final Groups allGroups = Groups.getInstance(); @@ -40,7 +41,7 @@ public void manage() { } public GroupType chooseGroup() { - while (true) { + while(true){ try { System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); String choice = nextLine(Message.END_MSG); @@ -48,18 +49,22 @@ public GroupType chooseGroup() { // "VIP" -> GroupType.VIP GroupType groupType = GroupType.valueOf(choice).replaceFullName(); // String -> enum return groupType; - } catch (InputEndException e) { + }catch (InputEndException e){ System.out.println(Message.ERR_MSG_INPUT_END); return null; - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException e){ System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); } } + } public void setParameter() { while (true) { GroupType groupType = chooseGroup(); + if(groupType == null){ + break; + } //GroupType에 해당하는 group객체를 찾아야함 Group group = allGroups.find(groupType); @@ -86,7 +91,9 @@ public void setParameter() { break; } allCustomers.refresh(); + } + } } From 564eb6e7d1b585b67fbd07b13590fae98b980615 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Wed, 10 May 2023 20:25:14 +0900 Subject: [PATCH 04/10] =?UTF-8?q?CustomerMenu=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/customer/Customer.java | 9 ++ me/smartstore/menu/CustomerMenu.java | 149 +++++++++++++++++++++++++-- 2 files changed, 148 insertions(+), 10 deletions(-) diff --git a/me/smartstore/customer/Customer.java b/me/smartstore/customer/Customer.java index 2e9c6d51..3e096f69 100644 --- a/me/smartstore/customer/Customer.java +++ b/me/smartstore/customer/Customer.java @@ -27,6 +27,14 @@ public Customer(String cName, String cId, Integer totalTime, Integer totalPay) { this.totalPay = totalPay; } + public Customer(String cName, String cId, Integer totalTime, Integer totalPay, Group group) { + this.cName = cName; + this.cId = cId; + this.totalTime = totalTime; + this.totalPay = totalPay; + this.group = group; + } + public String getcName() { return cName; } @@ -87,6 +95,7 @@ public String toString() { ", cId='" + cId + '\'' + ", totalTime=" + totalTime + ", totalPay=" + totalPay + + ", group=" + group + '}'; } } \ No newline at end of file diff --git a/me/smartstore/menu/CustomerMenu.java b/me/smartstore/menu/CustomerMenu.java index 532ad22c..e8ded3d4 100644 --- a/me/smartstore/menu/CustomerMenu.java +++ b/me/smartstore/menu/CustomerMenu.java @@ -1,6 +1,15 @@ package me.smartstore.menu; +import me.smartstore.customer.Customer; +import me.smartstore.customer.Customers; +import me.smartstore.exception.InputEndException; +import me.smartstore.exception.InputRangeException; + +import me.smartstore.util.Message; + + public class CustomerMenu implements Menu{ + private final Customers allCustomers = Customers.getInstance(); private static CustomerMenu customerMenu; public static CustomerMenu getInstance(){ @@ -15,18 +24,138 @@ private CustomerMenu(){} public void manage() { while (true) { int choice = chooseMenu(new String[]{ - "Add Customer", - "View Customer", - "Update Customer", - "Delete Customer", + "Set Customer Data", + "View Customer Data", + "Update Customer Data", + "Delete Customer Data", "Back" }); - if(choice == 1) {}//addCustomer(); - else if(choice == 2) {}//viewCustomer(); - else if(choice == 3) {}//updateCustomer(); - else if(choice == 4) {}//deleteCustomer(); + if(choice == 1) setCustomer(); + else if(choice == 2) viewCustomer(); + else if(choice == 3) updateCustomer(); + else if(choice == 4) deleteCustomer(); else break; } - } -} \ No newline at end of file + + public void setCustomer(){ + while(true){ + System.out.println("How many customers to input?"); + try{ + String num = nextLine(Message.END_MSG); + for(int i=0; i ", i+1)+ allCustomers.get(i)); + } + } + + private void updateCustomer() { + try { + viewCustomer(); + System.out.printf("Which customer ( 1 ~ %d )? ", allCustomers.size()); + Integer index = scanner.nextInt(); + scanner.nextLine(); + if(index <= 0 || index > allCustomers.size()){ + throw new InputRangeException(); + } + Customer customer = allCustomers.get(index - 1); + setCustomerManage(customer); + allCustomers.refresh(); + } catch (InputRangeException e){ + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + + private void deleteCustomer() { + try { + viewCustomer(); + System.out.printf("Which customer ( 1 ~ %d )? ", allCustomers.size()); + Integer index = scanner.nextInt(); + scanner.nextLine(); + if(index <= 0 || index > allCustomers.size()){ + throw new InputRangeException(); + } + System.out.println(allCustomers.get(index - 1)); + allCustomers.pop(index - 1); + viewCustomer(); + } catch (InputRangeException e){ + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + +} + + From 97c198e6ee5ce20f9a0d98b1349bc741a337cbc2 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Wed, 10 May 2023 23:27:28 +0900 Subject: [PATCH 05/10] =?UTF-8?q?SummaryMenu=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/customer/Customer.java | 6 +- me/smartstore/menu/OrderType.java | 33 ++++++++ me/smartstore/menu/SummaryMenu.java | 113 ++++++++++++++++++++++++++- 3 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 me/smartstore/menu/OrderType.java diff --git a/me/smartstore/customer/Customer.java b/me/smartstore/customer/Customer.java index 3e096f69..f536c4de 100644 --- a/me/smartstore/customer/Customer.java +++ b/me/smartstore/customer/Customer.java @@ -4,7 +4,7 @@ import java.util.Objects; -public class Customer { +public class Customer implements Comparable { private String cName; private String cId; private Integer totalTime; @@ -98,4 +98,8 @@ public String toString() { ", group=" + group + '}'; } + @Override + public int compareTo(Customer o) { + return this.cName.compareTo(o.cName); + } } \ No newline at end of file diff --git a/me/smartstore/menu/OrderType.java b/me/smartstore/menu/OrderType.java new file mode 100644 index 00000000..95795cff --- /dev/null +++ b/me/smartstore/menu/OrderType.java @@ -0,0 +1,33 @@ +package me.smartstore.menu; + +public enum OrderType { + + ASCENDING("오름차순"), + DESCENDING("내림차순"), + A("오름차순"), + D("내림차순"); + + String sortType = ""; + + OrderType(String sortType) { + this.sortType = sortType; + } + + public String getSortType() { + return this.sortType; + } + + public void setSortType(String sortType) { + this.sortType = sortType; + } + + public OrderType replaceFullName() { + if (this == A) + return ASCENDING; + if (this == D) + return DESCENDING; + return this; + } + + +} diff --git a/me/smartstore/menu/SummaryMenu.java b/me/smartstore/menu/SummaryMenu.java index f72c50fa..32ab3e5f 100644 --- a/me/smartstore/menu/SummaryMenu.java +++ b/me/smartstore/menu/SummaryMenu.java @@ -1,6 +1,24 @@ package me.smartstore.menu; +import me.smartstore.customer.Customer; +import me.smartstore.customer.Customers; +import me.smartstore.exception.InputEndException; +import me.smartstore.exception.InputRangeException; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; +import me.smartstore.group.Groups; +import me.smartstore.group.Parameter; +import me.smartstore.util.Message; + +import java.util.Arrays; +import java.util.Collections; + +import static me.smartstore.group.GroupType.*; + + public class SummaryMenu implements Menu { + private final Customers allCustomers = Customers.getInstance(); + private final Groups allGroups = Groups.getInstance(); private static SummaryMenu summaryMenu; public static SummaryMenu getInstance(){ @@ -21,12 +39,99 @@ public void manage() { "Summary (Sorted By Total Payment)", "Back" }); - if(choice == 1) {}//summary(); - else if(choice == 2) {}//sortedByName(); - else if(choice == 3) {}//sortedBySpentTime(); - else if(choice == 4) {}//sortedByTotalPayment(); + if(choice == 1) summary(getCustomer()); + else if(choice == 2) sortedByName(getCustomer()); + else if(choice == 3) sortedBySpentTime(getCustomer()); + else if(choice == 4) sortedByTotalPayment(getCustomer()); else break; } } + public Customer[] getCustomer(){ + Customer[] customers = new Customer[allCustomers.size()]; + for (int i=0; i< allCustomers.size(); i++){ + customers[i] = allCustomers.get(i); + } + return customers; + } + public void summary(Customer[] customers){ + Parameter parameter = null; + Group group; + GroupType[] groupType = {NONE, GENERAL, VIP, VVIP}; + for(GroupType type: groupType){ + for(int i=0; i ", i + 1) + customers[i]); + } + } + System.out.println(""); + } + } + + public OrderType orderTypeSummary() { + while(true){ + try { + System.out.println("Which order (ASCENDING (A), DESCENDING (D))?"); + String choice = nextLine(Message.END_MSG); + OrderType orderType = OrderType.valueOf(choice).replaceFullName(); + return orderType; + }catch (InputEndException e){ + System.out.println(Message.ERR_MSG_INPUT_END); + return null; + } catch (IllegalArgumentException e){ + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + + } + + + public void sortedByName(Customer[] customers){ + + while(true){ + OrderType orderType = orderTypeSummary(); + if(orderType == null){ + break; + } + try { + if(orderType == OrderType.ASCENDING){ + Arrays.sort(customers); + } + else if (orderType == OrderType.DESCENDING){ + Arrays.sort(customers, Collections.reverseOrder()); + } else { + throw new InputRangeException(); + } + summary(customers); + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } catch (InputRangeException e){ + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } + + + + public void sortedBySpentTime(Customer[] customers){ + + } + + + public void sortedByTotalPayment(Customer[] customers){ + + } + + } \ No newline at end of file From 8c2ea16211a89ba7074fd6be2f6c700fcbd34cec Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Wed, 10 May 2023 23:51:29 +0900 Subject: [PATCH 06/10] =?UTF-8?q?SummaryMenu=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20test=201.=20=EC=9D=B4=EB=A6=84=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=EA=B5=AC=ED=98=84=202.=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EA=B5=AC=ED=98=84=20X=203.=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EC=A0=95=EB=A0=AC=20=EA=B5=AC=ED=98=84=20X?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/menu/SummaryMenu.java | 107 ++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 31 deletions(-) diff --git a/me/smartstore/menu/SummaryMenu.java b/me/smartstore/menu/SummaryMenu.java index 32ab3e5f..9af13072 100644 --- a/me/smartstore/menu/SummaryMenu.java +++ b/me/smartstore/menu/SummaryMenu.java @@ -12,6 +12,7 @@ import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import static me.smartstore.group.GroupType.*; @@ -21,13 +22,15 @@ public class SummaryMenu implements Menu { private final Groups allGroups = Groups.getInstance(); private static SummaryMenu summaryMenu; - public static SummaryMenu getInstance(){ - if(summaryMenu == null){ + public static SummaryMenu getInstance() { + if (summaryMenu == null) { summaryMenu = new SummaryMenu(); } return summaryMenu; } - private SummaryMenu(){} + + private SummaryMenu() { + } @Override public void manage() { @@ -39,38 +42,40 @@ public void manage() { "Summary (Sorted By Total Payment)", "Back" }); - if(choice == 1) summary(getCustomer()); - else if(choice == 2) sortedByName(getCustomer()); - else if(choice == 3) sortedBySpentTime(getCustomer()); - else if(choice == 4) sortedByTotalPayment(getCustomer()); + if (choice == 1) summary(getCustomer()); + else if (choice == 2) sortedByName(getCustomer()); + else if (choice == 3) sortedBySpentTime(getCustomer()); + else if (choice == 4) sortedByTotalPayment(getCustomer()); else break; } } - public Customer[] getCustomer(){ + + public Customer[] getCustomer() { Customer[] customers = new Customer[allCustomers.size()]; - for (int i=0; i< allCustomers.size(); i++){ + for (int i = 0; i < allCustomers.size(); i++) { customers[i] = allCustomers.get(i); } return customers; } - public void summary(Customer[] customers){ + + public void summary(Customer[] customers) { Parameter parameter = null; Group group; GroupType[] groupType = {NONE, GENERAL, VIP, VVIP}; - for(GroupType type: groupType){ - for(int i=0; i ", i + 1) + customers[i]); } } @@ -79,16 +84,16 @@ public void summary(Customer[] customers){ } public OrderType orderTypeSummary() { - while(true){ + while (true) { try { System.out.println("Which order (ASCENDING (A), DESCENDING (D))?"); String choice = nextLine(Message.END_MSG); OrderType orderType = OrderType.valueOf(choice).replaceFullName(); return orderType; - }catch (InputEndException e){ + } catch (InputEndException e) { System.out.println(Message.ERR_MSG_INPUT_END); return null; - } catch (IllegalArgumentException e){ + } catch (IllegalArgumentException e) { System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); } } @@ -96,18 +101,17 @@ public OrderType orderTypeSummary() { } - public void sortedByName(Customer[] customers){ + public void sortedByName(Customer[] customers) { - while(true){ + while (true) { OrderType orderType = orderTypeSummary(); - if(orderType == null){ + if (orderType == null) { break; } try { - if(orderType == OrderType.ASCENDING){ - Arrays.sort(customers); - } - else if (orderType == OrderType.DESCENDING){ + if (orderType == OrderType.ASCENDING) { + Arrays.sort(customers); + } else if (orderType == OrderType.DESCENDING) { Arrays.sort(customers, Collections.reverseOrder()); } else { throw new InputRangeException(); @@ -116,20 +120,61 @@ else if (orderType == OrderType.DESCENDING){ } catch (InputEndException e) { System.out.println(Message.ERR_MSG_INPUT_END); break; - } catch (InputRangeException e){ + } catch (InputRangeException e) { System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); } } } - - public void sortedBySpentTime(Customer[] customers){ + public void sortedBySpentTime(Customer[] customers) { + while (true) { + OrderType orderType = orderTypeSummary(); + if (orderType == null) { + break; + } + try { + if (orderType == OrderType.ASCENDING) { + Arrays.sort(customers); + } else if (orderType == OrderType.DESCENDING) { + Arrays.sort(customers, Collections.reverseOrder()); + } else { + throw new InputRangeException(); + } + summary(customers); + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } } - public void sortedByTotalPayment(Customer[] customers){ + public void sortedByTotalPayment(Customer[] customers) { + while (true) { + OrderType orderType = orderTypeSummary(); + if (orderType == null) { + break; + } + try { + if (orderType == OrderType.ASCENDING) { + Arrays.sort(customers); + } else if (orderType == OrderType.DESCENDING) { + Arrays.sort(customers, Collections.reverseOrder()); + } else { + throw new InputRangeException(); + } + summary(customers); + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } } From 42bf39d15d02728b37b5266481775a4dc27bd524 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Wed, 10 May 2023 23:51:41 +0900 Subject: [PATCH 07/10] =?UTF-8?q?SummaryMenu=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20test=201.=20=EC=9D=B4=EB=A6=84=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=EA=B5=AC=ED=98=84=202.=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EA=B5=AC=ED=98=84=20X=203.=20=EA=B8=88?= =?UTF-8?q?=EC=95=A1=20=EC=A0=95=EB=A0=AC=20=EA=B5=AC=ED=98=84=20X?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/group/Groups.java | 1 + 1 file changed, 1 insertion(+) diff --git a/me/smartstore/group/Groups.java b/me/smartstore/group/Groups.java index 2b465b44..4340338b 100644 --- a/me/smartstore/group/Groups.java +++ b/me/smartstore/group/Groups.java @@ -8,6 +8,7 @@ public class Groups extends DArray { public static Groups getInstance(){ if(allGroups == null){ allGroups = new Groups(); + allGroups.add(new Group(new Parameter(), GroupType.NONE)); } return allGroups; } From aa82427a02c4506c452754d5cbf4af04b784b174 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Thu, 11 May 2023 00:03:40 +0900 Subject: [PATCH 08/10] =?UTF-8?q?SummaryMenu=20=EA=B5=AC=ED=98=84=20Test?= =?UTF-8?q?=202,3=20=EA=B5=AC=ED=98=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/customer/Customer.java | 2 +- me/smartstore/menu/SummaryMenu.java | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/me/smartstore/customer/Customer.java b/me/smartstore/customer/Customer.java index f536c4de..71da4ee5 100644 --- a/me/smartstore/customer/Customer.java +++ b/me/smartstore/customer/Customer.java @@ -100,6 +100,6 @@ public String toString() { } @Override public int compareTo(Customer o) { - return this.cName.compareTo(o.cName); + return this.compareTo(o); } } \ No newline at end of file diff --git a/me/smartstore/menu/SummaryMenu.java b/me/smartstore/menu/SummaryMenu.java index 9af13072..1e9ea3b9 100644 --- a/me/smartstore/menu/SummaryMenu.java +++ b/me/smartstore/menu/SummaryMenu.java @@ -135,9 +135,19 @@ public void sortedBySpentTime(Customer[] customers) { } try { if (orderType == OrderType.ASCENDING) { - Arrays.sort(customers); + Arrays.sort(customers, new Comparator() { + @Override + public int compare(Customer o1, Customer o2) { + return o1.getTotalTime() - o2.getTotalTime(); + } + }); } else if (orderType == OrderType.DESCENDING) { - Arrays.sort(customers, Collections.reverseOrder()); + Arrays.sort(customers, new Comparator() { + @Override + public int compare(Customer o1, Customer o2) { + return o1.getTotalTime() - o2.getTotalTime(); + } + }); } else { throw new InputRangeException(); } @@ -161,9 +171,19 @@ public void sortedByTotalPayment(Customer[] customers) { } try { if (orderType == OrderType.ASCENDING) { - Arrays.sort(customers); + Arrays.sort(customers, new Comparator() { + @Override + public int compare(Customer o1, Customer o2) { + return o1.getTotalPay() - o2.getTotalPay(); + } + }); } else if (orderType == OrderType.DESCENDING) { - Arrays.sort(customers, Collections.reverseOrder()); + Arrays.sort(customers, new Comparator() { + @Override + public int compare(Customer o1, Customer o2) { + return o2.getTotalPay() - o1.getTotalPay(); + } + }); } else { throw new InputRangeException(); } From 00a79a2ef20a79275f9c86a9ea056704777251a5 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Thu, 11 May 2023 00:08:07 +0900 Subject: [PATCH 09/10] =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- me/smartstore/menu/SummaryMenu.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/me/smartstore/menu/SummaryMenu.java b/me/smartstore/menu/SummaryMenu.java index 1e9ea3b9..513cf0f3 100644 --- a/me/smartstore/menu/SummaryMenu.java +++ b/me/smartstore/menu/SummaryMenu.java @@ -100,7 +100,7 @@ public OrderType orderTypeSummary() { } - + //이름 순서 정렬 public void sortedByName(Customer[] customers) { while (true) { @@ -126,7 +126,7 @@ public void sortedByName(Customer[] customers) { } } - + //시간 순서 정렬 public void sortedBySpentTime(Customer[] customers) { while (true) { OrderType orderType = orderTypeSummary(); @@ -145,7 +145,7 @@ public int compare(Customer o1, Customer o2) { Arrays.sort(customers, new Comparator() { @Override public int compare(Customer o1, Customer o2) { - return o1.getTotalTime() - o2.getTotalTime(); + return o2.getTotalTime() - o1.getTotalTime(); } }); } else { @@ -162,7 +162,7 @@ public int compare(Customer o1, Customer o2) { } - + //금액 순서 정렬 public void sortedByTotalPayment(Customer[] customers) { while (true) { OrderType orderType = orderTypeSummary(); From 4404567984e600ed96a5f64417c7c307213c6541 Mon Sep 17 00:00:00 2001 From: Horaiz-UQ Date: Thu, 11 May 2023 00:15:29 +0900 Subject: [PATCH 10/10] =?UTF-8?q?jar=20=ED=8C=8C=EC=9D=BC=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KDTBE5_Java_ToyProject.jar | Bin 0 -> 40194 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 out/artifacts/KDTBE5_Java_ToyProject_jar/KDTBE5_Java_ToyProject.jar diff --git a/out/artifacts/KDTBE5_Java_ToyProject_jar/KDTBE5_Java_ToyProject.jar b/out/artifacts/KDTBE5_Java_ToyProject_jar/KDTBE5_Java_ToyProject.jar new file mode 100644 index 0000000000000000000000000000000000000000..e183efc3f02025c2397da51fb6ed3b348c44d80f GIT binary patch literal 40194 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

FmDOObiv+{G+9C4CrB-#%ij)&icc|Oqv~eW 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 WZ}=_DH&qxpLVx3}S@w9%pZ)+U^cRo- literal 0 HcmV?d00001