5
\$\begingroup\$

I implemented a sign in from different accounts on which different amounts of money lie. You must also specify what will be sold in the store. When you buy, you can put things in the basket, get them out of there, empty the basket. When you exit, the transaction will occur, and money will be withdrawn from your account. I really tried to do it right. Point out my mistakes, if they are present, please.

void main():

public static void main(String[] args) throws CloneNotSupportedException {
    Account user = new Account("olenushka", "wolf", 300);
    Account[] dataBase = {
            new Account("ivan","swan", 200),
            new Account("fox","tail", 500),
            new Account("olenushka", "wolf", 300)
    };
    Product[] assortiment = {
            new Product("chips",20,10),
            new Product("cola", 30, 5),
            new Product("crackers", 10, 50),
            new Product("wine", 100, 3),
            new Product("bread", 15, 4)
    };
    Shop shopInTheForest = new Shop(dataBase,assortiment);
    shopInTheForest.play(user);
}

class Shop:

skeleton:

public class Shop {
    private Account[] dataBase;
    private Product[] assortiment;
    private Product[] basket; // i could create it as int[], but... its does not looks good

    private final static String CHOOSE = "Print the product number and its quantity(\"add number quantity\", or \"add number\", if quantity = 1) to add it in a basket\n"
                                      + "Print \"buy and exit\" if u want to exit and buy all that contains in a basket, \n"
                                      + "\"exit\" if u want to exit without buying all that contains in a basket, \n"
                                      + "\"delete number\" if u want to delete smth from a basket, \n"
                                      + "\"clear\" if u want to clear basket, \n"
                                      + "\"print\" if u want print all products contains in a basket:):"; 
    private final static String THANKS = "Thank u, come to us again!";
    private final static String OKEY = "okey"; // can i use enum?

    public Shop(Account[] dataBase, Product[] assortiment) throws CloneNotSupportedException{
        this.dataBase = dataBase;
        this.assortiment = assortiment;
    }

    public void play(Account user) throws CloneNotSupportedException {
        AccountAndDataBase userAndDataBaseClone;
        if(user == null) {
            System.err.println("user is not declared!");
            return;
        }
        if(!Account.isIn(dataBase, user)) {
            System.err.println("user " + user.getLogin() + " is not in the database!");
            return;
        }
        userAndDataBaseClone = GetAccountAndDataBaseAfterBuyingAllFromBasketAfterPuttingInABasket(user);
        System.out.println(THANKS);
        System.out.println("Ur account stats: " + userAndDataBaseClone.getAccount().toStringMoney());
        if(isEmpty(basket)) {
            System.out.println("U bought nothing");
        } else {
            System.out.println("U bought : ");
            Product.print(basket);
        }
    }

    private boolean isEmpty(Product[] basket) {}

    private AccountAndDataBase GetAccountAndDataBaseAfterBuyingAllFromBasketAfterPuttingInABasket(Account user) throws CloneNotSupportedException {}


    private boolean isNumbers(String[] splitted) {}

    private Product[] toGetEmptyBasket() {}

    private void deleteFromABasket(Product[] assortimentClone, Account userClone, int id) {}

    private void addToABasket(Product[] assortimentClone, Account userClone, int id, int selectedQuantity) {}

    private void toClearBasket(Product[] assortimentClone, Account userClone) {}

    private int[] getProductNumberAndQuantity(String command) {}


    private String commandFormStatusForDeleting(String commandWithoutKeyWord) {}

    private String commandFormStatusForAdding(String command) {}

    private boolean isNumber(String str) {}

    private boolean isNumber(char c) {}
}

full code:

public class Shop {
    private Account[] dataBase;
    private Product[] assortiment;
    private Product[] basket; // i could create it as int[], but... its does not looks good

    private final static String CHOOSE = "Print the product number and its quantity(\"add number quantity\", or \"add number\", if quantity = 1) to add it in a basket\n"
                                      + "Print \"buy and exit\" if u want to exit and buy all that contains in a basket, \n"
                                      + "\"exit\" if u want to exit without buying all that contains in a basket, \n"
                                      + "\"delete number\" if u want to delete smth from a basket, \n"
                                      + "\"clear\" if u want to clear basket, \n"
                                      + "\"print\" if u want print all products contains in a basket:):"; 
    private final static String THANKS = "Thank u, come to us again!";
    private final static String OKEY = "okey"; // can i use enum?

    public Shop(Account[] dataBase, Product[] assortiment) throws CloneNotSupportedException{
        this.dataBase = dataBase;
        this.assortiment = assortiment;
    }

    public void play(Account user) throws CloneNotSupportedException {
        AccountAndDataBase userAndDataBaseClone;
        if(user == null) {
            System.err.println("user is not declared!");
            return;
        }
        if(!Account.isIn(dataBase, user)) {
            System.err.println("user " + user.getLogin() + " is not in the database!");
            return;
        }
        userAndDataBaseClone = GetAccountAndDataBaseAfterBuyingAllFromBasketAfterPuttingInABasket(user);
        System.out.println(THANKS);
        System.out.println("Ur account stats: " + userAndDataBaseClone.getAccount().toStringMoney());
        if(isEmpty(basket)) {
            System.out.println("U bought nothing");
        } else {
            System.out.println("U bought : ");
            Product.print(basket);
        }
    }

    private boolean isEmpty(Product[] basket) {
        for(Product p : basket) {
            if(p.getCount() != 0) {
                return false;
            }
        }
        return true;
    }

    private AccountAndDataBase GetAccountAndDataBaseAfterBuyingAllFromBasketAfterPuttingInABasket(Account user) throws CloneNotSupportedException {
        Scanner scanner = new Scanner(System.in);
        boolean needToPrintBasket = false;
        int[] selectedProductNumberAndQuantity;
        int selectedProductNumber, selectedQuantity;
        Product selectedProductInAssortiment;
        String command;
        String firstWordOfCommand;
        String commandWithoutKeyWord;
        String forError;
        Account userClone = user.clone();
        Product[] assortimentClone = assortiment.clone();

        basket = toGetEmptyBasket();
        while(true) {
            System.out.println(userClone.toStringMoney());
            if(needToPrintBasket) {
                System.out.println("Basket: ");
                Product.print(basket);
                needToPrintBasket = false;
            }
            System.out.println(CHOOSE);
            Product.print(assortimentClone);
            command = scanner.nextLine();
            if(command.isEmpty()) {
                System.out.println("command is empty");
                continue;
            }
            //buy and exit
            if(command.equals("buy and exit")) {
                break;
            }
            //exit
            if(command.equals("exit")) {
                toClearBasket(assortimentClone, userClone);
                break;
            }
            //print
            if(command.equals("print")) {
                needToPrintBasket = true;
                continue;
            }
            //clear
            if(command.equals("clear")) {
                toClearBasket(assortimentClone, userClone);
                continue;
            }

            if(command.indexOf(' ') == -1) {
                System.out.println("I cannot understand ur command");
                continue;
            }
            firstWordOfCommand = command.substring(0,command.indexOf(" "));
            commandWithoutKeyWord = command.substring(command.indexOf(" ")+1);
            if(firstWordOfCommand.isEmpty() || commandWithoutKeyWord.isEmpty()) {
                System.out.println("I cannot understand ur command");
                continue;
            }
            if(!isNumbers(commandWithoutKeyWord.split(" "))) {
                System.out.println("One of number's field is not number");
                continue;
            }
            if(commandWithoutKeyWord.split(" ").length > 2) {
                System.out.println("Too many arguments after key word");
                continue;
            }
            selectedProductNumberAndQuantity = getProductNumberAndQuantity(commandWithoutKeyWord);
            selectedProductNumber = selectedProductNumberAndQuantity[0];
            selectedQuantity = selectedProductNumberAndQuantity[1];
            if(assortimentClone.length < selectedProductNumber) {
                System.out.println("selected product number is over assortiment's length");
                continue;
            }
            if(selectedProductNumber < 1) {
                System.out.println("selected product number is < 1");
                continue;
            }
            //delete
            if(firstWordOfCommand.toLowerCase().equals("delete") && !(forError = commandFormStatusForDeleting(commandWithoutKeyWord)).equals(OKEY)) {
                System.out.println(forError);
                continue;
            }else if(firstWordOfCommand.toLowerCase().equals("delete")){
                if(assortimentClone[selectedProductNumber-1].getCount() < selectedQuantity) {
                    System.out.println("selected product quantity must be <= product's quantity in assortiment");
                    continue;
                }
                deleteFromABasket(assortimentClone, userClone, selectedProductNumber-1);
                continue;
            }
            //add
            if(firstWordOfCommand.toLowerCase().equals("add") && !(forError = commandFormStatusForAdding(commandWithoutKeyWord)).equals(OKEY)) {
                System.out.println(forError);
                continue;
            }else if(firstWordOfCommand.toLowerCase().equals("add")){
                selectedProductInAssortiment = assortimentClone[selectedProductNumber-1];
                if((selectedProductInAssortiment.getPrice() * selectedQuantity) > userClone.getMoney()) {
                    System.out.println("U have not got enougth money. U can buy only "+((int) userClone.getMoney() / selectedProductInAssortiment.getPrice()) + " " + selectedProductInAssortiment.getName());
                    continue;
                }
                if(selectedProductInAssortiment.getCount() < selectedQuantity) {
                    System.out.println("There are only " + selectedProductInAssortiment.getCount() + " in assortiment");
                    continue;
                }
                addToABasket(assortimentClone, userClone, selectedProductNumber-1, selectedQuantity);
                continue;
            }

            System.out.println("I cannot understand ur command");
        }
        return new AccountAndDataBase(userClone, assortimentClone);
    }


    private boolean isNumbers(String[] splitted) {
        for(int i = 0; i < splitted.length; i++) {
            if(!isNumber(splitted[i])) {
                return false;
            }
        }
        return true;
    }

    private Product[] toGetEmptyBasket() {
        Product[] basket = new Product[assortiment.length];
        for(int i = 0; i < basket.length; i++) {
            basket[i] = new Product(assortiment[i].getName(),assortiment[i].getPrice(),0);
        }
        return basket;
    }

    private void deleteFromABasket(Product[] assortimentClone, Account userClone, int id) {
        userClone.addMoney(basket[id].getCount() * basket[id].getPrice());
        assortimentClone[id].addCount(basket[id].getCount());
        basket[id].setCount(0);
    }

    private void addToABasket(Product[] assortimentClone, Account userClone, int id, int selectedQuantity) {
        userClone.removeMoney(selectedQuantity * basket[id].getPrice());
        assortimentClone[id].removeCount(selectedQuantity);
        basket[id].addCount(selectedQuantity);
    }

    private void toClearBasket(Product[] assortimentClone, Account userClone) {
        for(int id = 0; id < basket.length; id++) {
            userClone.addMoney(basket[id].getCount() * basket[id].getPrice());
            assortimentClone[id].addCount(basket[id].getCount());
            basket[id].setCount(0);
        }
    }

    private int[] getProductNumberAndQuantity(String command) {
        final String[] commandSplitted = command.split(" ");
        if(commandSplitted.length == 1) {
            return new int[] {Integer.parseInt(commandSplitted[0]),1};
        }
        else { // length == 2
            return new int[] {Integer.parseInt(commandSplitted[0]),Integer.parseInt(commandSplitted[1])};
        }
    }


    private String commandFormStatusForDeleting(String commandWithoutKeyWord) {
        if(commandWithoutKeyWord.indexOf(' ') != -1) {
            return "There are must to be only 1 space";
        }
        if(!isNumber(commandWithoutKeyWord)) {
            return "product number should be number";
        }
        return OKEY;
    }

    private String commandFormStatusForAdding(String command) {
        final int countOfSpaces = (int) command.chars().filter(c -> c == ' ').count();
        final String[] commandSplitted;

        if(countOfSpaces != 1 && countOfSpaces != 0) {
            return "command must has only 1 or 0 spaces!";
        }
        commandSplitted = command.split(" ");
        if(!isNumber(commandSplitted[0])) {
            return "product number must be number";
        }
        if(countOfSpaces == 1 && !isNumber(commandSplitted[1])) {
            return "product quantity must be number";
        }
        return OKEY;
    }

    private boolean isNumber(String str) {
        for(char c:str.toCharArray()) {
            if(!isNumber(c)) {
                return false;
            }
        }
        return true;
    }

    private boolean isNumber(char c) {
        return c == '0' || c == '1' || c == '2' || c == '3' || c == '4' ||
               c == '5' || c == '6' || c == '7' || c == '8' || c == '9' ;
    }
}

class AccountAndDataBase:

full code:

public class AccountAndDataBase{
    private Account account;
    private Product[] dataBase;

    public AccountAndDataBase(Account account, Product[] dataBase) throws CloneNotSupportedException{
        this.account = account.clone(); // for safety
        this.dataBase = Product.clone(dataBase);
    }
    Account getAccount() {
        return account;
    }
    Product[] getDataBase(){
        return dataBase;
    }
}

class Product:

full code:

public class Product implements Cloneable{
    private String name;
    private int price;
    private int count;


    public Product(String name, int price, int count) {
        this.name = name;
        this.price = price;
        this.count = count;
    }


    public static void print(Product[] assortiment) {
        for(int i = 0; i < assortiment.length; i++) {
            System.out.println((i + 1) + ". " + assortiment[i].getName() + " costs " + assortiment[i].getPrice() + ". There are " + assortiment[i].getCount());
        }
    }

    public static void clear(Product[] basket) {
        for(Product p:basket) {
            p.setCount(0);
        }
    }

    public static Product[] clone(Product[] dataBase) throws CloneNotSupportedException {
        Product[] dataBaseReturn = new Product[dataBase.length];
        for(int i = 0; i < dataBase.length; i++) {
            dataBaseReturn[i] = dataBase[i].clone();
        }
        return dataBaseReturn;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getName() {
        return name;
    }

    public int getPriceOfAll() {
        return price*count;
    }

    public int getPrice() {
        return price;
    }

    public int getCount() {
        return count;
    }

    public void addCount(int toAdd) {
        count+=toAdd;
    }

    public Product clone() throws CloneNotSupportedException {
        return (Product) super.clone();
    }

    public void removeCount(int selectedQuantity) {
        count-=selectedQuantity;
    }


}

class Account:

full code:

public class Account implements Cloneable{
    private int money;
    private String login;
    private String password;


    public Account(String login, String password, int money) {
        this.login = new String(login);
        this.password = new String(password);
        this.money = money;
    }


    public static Account[] clone(Account[] dataBase) throws CloneNotSupportedException {
        Account[] dataBaseReturn = new Account[dataBase.length];
        for(int i = 0; i < dataBase.length; i++) {
            dataBaseReturn[i] = dataBase[i].clone();
        }
        return dataBaseReturn;
    }

    public static boolean isIn(Account[] dataBase, Account user) {
        for(Account u : dataBase) {
            if(user.equals(u)) {
                return true; 
            }
        }
        return false;
    }

    public String toStringMoney() {
        return "Account \"" + login + "\" has " + money + " money";
    }

    public int getMoney() {
        return money;
    }

    public Account clone() throws CloneNotSupportedException {
        return (Account) super.clone();
    }

    public void addMoney(int toAdd) {
        this.money += toAdd;

    }

    public void removeMoney(int toRemove) {
        this.money -= toRemove;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj == null || !(obj instanceof Account)) {
            return false;
        }
        Account a = (Account) obj;
        return a.getMoney() == money && a.getPassword().equals(getPassword()) && a.getLogin().equals(getLogin());
    }

    public String getLogin() {
        return login;
    }

    private Object getPassword() {
        return password;
    }

}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I have some suggestions for your code, the first thing I saw from your main method is the use of CloneNotSupportedException

Create a copy constructor instead of using clone() method

I have taken your Product class and added a copy constructor to avoid the use of CloneNotSupportedException like the code below:

public class Product {
    private String name;
    private int price;
    private int count;

    public Product(String name, int price, int count) {
        this.name = name;
        this.price = price;
        this.count = count;
    }

    //copy constructor for one product
    public Product(Product product) {
        this.name = product.name;
        this.price = product.price;
        this.count = product.count;
    }
}

If you want to print the internal state of an object override the toString method and return a String:

@Override
public String toString() {
    return String.format("%s costs %d. There are %d", name, price, count);
}

Now you can use the toString method to print an array of Product:

public static void print(Product[] assortiment) {
    final int n = assortiment.length;
    for(int i = 0; i < n; ++i) {
        System.out.println((i + 1) + ". " + assortiment[i]);
    }
}

To obtain a copy of an array you can use the method Arrays.copyOf

public static Product[] copyOf(Product[] original) {
    final int n = original.length;
    Product[] copy = Arrays.copyOf(original, n);
    return copy;
}

These code changes could be applied to other classes in your code. I have seen in your code the following lines:

public void play(Account user) throws CloneNotSupportedException {
    AccountAndDataBase userAndDataBaseClone;
    if(user == null) {
        System.err.println("user is not declared!");
        return;
    }
    if(!Account.isIn(dataBase, user)) {
        System.err.println("user " + user.getLogin() + " is not in the database!");
        return;
    }
...omitted
}

This implies that when you pass illegal arguments to one method the method fails printing a message on the screen; for dealing with illegal arguments you can use the IllegalArgumentException class and construct a custom message for the exception like the code below:

public void play(Account user) throws CloneNotSupportedException {
    AccountAndDataBase userAndDataBaseClone;
    if(user == null) {
        throw new IllegalArgumentException("user is not declared!");
    }
    if(!Account.isIn(dataBase, user)) {
        throw new IllegalArgumentException("user " + user.getLogin() + " is not in the database!");
    }
...omitted
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.