• ,

task.task26.task2613 Задание 8

CashMachine (8)

Пора привести в порядок наш main, уж очень там всего много, чего не должно быть.

1. Перенеси логику из main в DepositCommand и InfoCommand.

Проверим, что там стало с main? Цикл, в котором спрашиваем операцию у пользователя, а потом вызываем метод у CommandExecutor.

И так до бесконечности… надо бы придумать условие выхода из цикла.

Исправь цикл, чтоб он стал do-while. Условие выхода — операция EXIT.

2. Давай запустим прогу и пополним счет на EUR 100 2 и USD 20 6, и посмотрим на INFO.

Ничего не понятно, т.к. создались 2 манипулятора: первый для EUR, второй для USD.

Давай улучшим логику InfoCommand. Надо вывести баланс по каждому манипулятору.

2.1. В классе CurrencyManipulatorFactory создай статический метод getAllCurrencyManipulators(), который вернет Collection всех манипуляторов.

У тебя все манипуляторы хранятся в карте, не так ли? Если нет, то отрефактори.

2.2. В InfoCommand в цикле выведите [код валюты — общая сумма денег для выбранной валюты].

Запустим прогу и пополним счет на EUR 100 2 и USD 20 6, и посмотрим на INFO.

Все работает правильно?

EUR — 200

USD — 120

Отлично!

3. Запустим прогу и сразу первой операцией попросим INFO. Ничего не вывело? Непорядок.

Добавь в манипулятор метод boolean hasMoney(), который будет показывать, добавлены ли какие-то банкноты или нет.

4. В InfoCommand используй метод п.3. и выведите фразу «No money available.«, если нет денег в банкомате.
  • ,

level26.lesson15.big01 Задание 10

Добрый день. Прошу у всех помощи. Сижу с задачей 2 неделю, перепробовал большое кол-во вариантов написания кода. Ничего не принимает. Сейчас пишет, что не компилируется на сервере. Но вывод правильный.
Задание 10
Сегодня мы займемся командой WithdrawCommand - это самая сложная операция.

1. Реализуйте следующий алгоритм для команды WithdrawCommand:
1.1. Считать код валюты (метод уже есть)
1.2. Получить манипулятор для этой валюты.
1.3. Пока пользователь не введет корректные данные выполнять:
1.3.1. Попросить ввести сумму
1.3.2. Если введены некорректные данные, то сообщить об этом пользователю и вернуться к п. 1.3.
1.3.3. Проверить, достаточно ли средств на счету.
Для этого в манипуляторе создайте метод boolean isAmountAvailable(int expectedAmount), который вернет true, если денег достаточно для выдачи.
Если недостаточно, то вернуться к п. 1.3.
1.3.4. Списать деньги со счета. Для этого в манируляторе создайте метод
Map<Integer, Integer> withdrawAmount(int expectedAmount), который вернет карту Map<номинал, количество>.
Подробно логику этого метода смотрите в п.2.
1.3.5. Вывести пользователю результат из п. 1.3.4. в следующем виде:
<табуляция>номинал - количество
Сортировка - от большего номинала к меньшему.
Вывести сообщение об успешной транзакции.
1.3.6. Перехватить исключение NotEnoughMoneyException, уведомить юзера о нехватке банкнот и вернуться к п. 1.3.

2. Логика основного метода withdrawAmount:
2.1. Внимание!!! Метод withdrawAmount должен возвращать минимальное количество банкнот, которыми набирается запрашиваемая сумма.
Используйте Жадный алгоритм (use google).
Если есть несколько вариантов, то использовать тот, в котором максимальное количество банкнот высшего номинала.
Если для суммы 600 результат - три банкноты: 500 + 50 + 50 = 200 + 200 + 200, то выдать первый вариант.
Пример, надо выдать 600
В манипуляторе есть следующие банкноты:
500 - 2
200 - 3
100 - 1
50 - 12
Результат должен быть таким:
500 - 1
100 - 1
т.е. всего две банкноты (это минимальное количество банкнот) номиналом 500 и 100.

2.2. Мы же не можем одни и те же банкноты выдавать несколько раз, поэтому
если мы нашли вариант выдачи денег (п.2.1. успешен), то вычесть все эти банкноты из карты в манипуляторе.

2.3. метод withdrawAmount должен кидать NotEnoughMoneyException, если купюрами невозможно выдать запрашиваемую сумму.
Пример, надо выдать 600
В манипуляторе есть следующие банкноты:
500 - 2
200 - 2
Результат - данными банкнотами невозможно выдать запрашиваемую сумму. Кинуть исключение.
Не забудьте, что в некоторых случаях картой кидается ConcurrentModificationException.

public Map<Integer, Integer> withdrawAmount(int expectedAmount) throws NotEnoughMoneyException
    {
        int sum = expectedAmount;
        HashMap<Integer, Integer> temp = new HashMap<>();
        temp.putAll(denominations);
        ArrayList<Integer> list = new ArrayList<>();
        for (Map.Entry<Integer, Integer> pair : temp.entrySet())
            list.add(pair.getKey());

        Collections.sort(list);
        Collections.reverse(list);

        TreeMap<Integer, Integer> result = new TreeMap<>(new Comparator<Integer>()
        {
            @Override
            public int compare(Integer o1, Integer o2)
            {
                return o2.compareTo(o1);
            }
        });

        for (Integer aList : list) {
            int key = aList;
            int value = temp.get(key);
            while (true) {
                if (sum < key || value <= 0) {
                    temp.put(key, value);
                    break;
                }
                sum -= key;
                value--;

                if (result.containsKey(key))
                    result.put(key, result.get(key) + 1);
                else
                    result.put(key, 1);
            }
        }

        if (sum > 0)
            throw new NotEnoughMoneyException();
        else
        {
            for (Map.Entry<Integer, Integer> pair : result.entrySet())
                ConsoleHelper.writeMessage("\t" + pair.getKey() + " - " + pair.getValue());

            denominations.clear();
            denominations.putAll(temp);
            ConsoleHelper.writeMessage("Transaction was successful!");
        }
        return result;
    }


public void execute() throws InterruptOperationException
    {
        String currencyCode = ConsoleHelper.askCurrencyCode();
        CurrencyManipulator currencyManipulator = CurrencyManipulatorFactory.getManipulatorByCurrencyCode(currencyCode);
        int sum;
        while(true)
        {
            ConsoleHelper.writeMessage("Введите сумму");
            String s = ConsoleHelper.readString();
            try
            {
                sum = Integer.parseInt(s);
            } catch (NumberFormatException e)
            {
                ConsoleHelper.writeMessage("Только цифры");
                continue;
            }
            if (sum <= 0)
            {
                ConsoleHelper.writeMessage("Цифры больше нуля");
                continue;
            }
            if (!currencyManipulator.isAmountAvailable(sum))
            {
                ConsoleHelper.writeMessage("Не хватает денег");
                continue;
            }
            try
            {
                currencyManipulator.withdrawAmount(sum);
            } catch (NotEnoughMoneyException e)
            {
                ConsoleHelper.writeMessage("Не хватает банкнот");
                continue;
            }
            break;
        }

    }

level26.lesson15.big01 Задание 3

package com.javarush.test.level26.lesson15.big01;

import java.util.ArrayList;

/**
 * Created by RustedBrain on 14.06.2015.
 */
public class CurrencyManipulatorFactory
{
    private static CurrencyManipulatorFactory ourInstance = new CurrencyManipulatorFactory();
    private static ArrayList<CurrencyManipulator> manipulators = new ArrayList<>();

    private CurrencyManipulatorFactory()
    {
    }

    public static CurrencyManipulatorFactory getInstance()
    {
        return ourInstance;
    }

    public static CurrencyManipulator getManipulatorByCurrencyCode(String currencyCode)
    {
        for (CurrencyManipulator manipulator : manipulators)
        {
            if (manipulator.getCurrencyCode().equals(currencyCode))
                return manipulator;
        }
        return new CurrencyManipulator(currencyCode);
    }
}


Подскажие пожалуйста что возможно не верно, условия следующие:
Создадим класс CurrencyManipulatorFactory со статическим методом getManipulatorByCurrencyCode(String currencyCode).
В этом методе будем создавать нужный манипулятор, если он еще не существует, либо возвращать ранее созданный.
Подумайте, где лучше хранить все манипуляторы.
Сделайте так, чтобы невозможно было создавать объекты CurrencyManipulatorFactory класса

level26.lesson15.big01 Задание 4

Помогите найти ошибку. Сервер не хочет принимать задачу

Задание 4
1. Выберем операцию, с которой мы сможем начать.
Подумаем. В банкомате еще денег нет, поэтому INFO и WITHDRAW протестить не получится.
Начнем с операции DEPOSIT — поместить деньги.
Считаем с консоли код валюты, потом считаем номинал и количество банкнот, а потом добавим их в манипулятор.

2. Чтобы считать код валюты, добавим статический метод String askCurrencyCode() в ConsoleHelper.
Этот метод должен предлагать пользователю ввести код валюты, проверять, что код содержит 3 символа.
Если данные некорректны, то сообщить об этом пользователю и повторить.
Если данные валидны, то перевести код в верхний регистр и вернуть.

3. Чтобы считать номинал и количество банкнот, добавим статический метод String[] getValidTwoDigits(String currencyCode) в ConsoleHelper.
Этот метод должен предлагать пользователю ввести два целых положительных числа.
Первое число — номинал, второе — количество банкнот.
Никаких валидаторов на номинал нет. Т.е. 1200 — это нормальный номинал.
Если данные некорректны, то сообщить об этом пользователю и повторить.
Пример вводимых данных:
200 5

4. В классе CurrencyManipulator создайте метод void addAmount(int denomination, int count),
который добавит введенные номинал и количество банкнот

5. Пора уже увидеть приложение в действии.
В методе main захардкодь логику пункта 1.
Кстати, чтобы не было проблем с тестами на стороне сервера, добавь в метод main первой строчкой Locale.setDefault(Locale.ENGLISH);
Запускаем, дебажим, смотрим.

Помогите найти ошибку. Сервер не хочет принимать задачу

public class CashMachine
{


    public static void main(String[] args)
    {
        Locale.setDefault(Locale.ENGLISH);
        String code = ConsoleHelper.askCurrencyCode();
        String[] nominalCount = ConsoleHelper.getValidTwoDigits(code);
        CurrencyManipulator manipulator = CurrencyManipulatorFactory.getManipulatorByCurrencyCode(code);
        manipulator.addAmount(Integer.parseInt(nominalCount[0]), Integer.parseInt(nominalCount[1]));
    }
}

public class CurrencyManipulator
{
    private String currencyCode;
    Map<Integer, Integer> denominations = new HashMap<>();

    public CurrencyManipulator(String currencyCode)
    {
        this.currencyCode = currencyCode;
    }

    public String getCurrencyCode()
    {
        return currencyCode;
    }

    void addAmount(int denomination, int count) {
        Integer currentCount = denominations.get(denomination);
        if (currentCount == null)
            denominations.put(denomination, count);
        else denominations.put(denomination, currentCount + count);
    }
}

public class ConsoleHelper
{
    private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

    public static void writeMessage(String message)
    {
        System.out.println(message);
    }

    public static String readString()
    {
        String line = null;
        try
        {
            line = reader.readLine();
        }
        catch (IOException e)
        {
        }
        return line;
    }

    public static String askCurrencyCode()
    {
        String code = null;

        do
        {
            writeMessage("Input currency code:");
            code = readString();
            if (code == null || code.length() != 3)
            {
                writeMessage("Invalid currency code.");
            }
        }
        while (code == null || code.length() != 3);

        return code.toUpperCase();
    }

    public static String[] getValidTwoDigits(String currencyCode)
    {
        String line = null;

        do
        {
            writeMessage("Input nominal and amount:");

            line = readString();
            if (line != null && line.matches("\\d+ \\d+"))
                return line.split(" ");


            writeMessage("Invalid nominal and amount");
        }
        while (true);
    }
}
  • ,

level26.lesson15.big01 Задание 9

Завис на этом задании, пересмотрел все варианты.

Задание 9
Сегодня мы займемся командой ExitCommand.
1. Реализуйте следующую логику в команде ExitCommand:
1.1. Спросить, действительно ли пользователь хочет выйти — варианты <y,n>.
1.2. Если пользователь подтвердит свои намерения, то попрощаться с ним.

Это всё хорошо, но бывают случаи, когда срочно нужно прервать операцию, например, если пользователь ошибся с выбором операции.
Для этого у нас есть InterruptOperationException.
2.Реализуйте следующую логику:
2.1. Если пользователь в любом месте ввел текст 'EXIT' любым регистром, то выбросить InterruptOperationException.
2.2. Найдите единственное место, куда нужно вставить эту логику. Реализуйте функционал в этом единственном методе.

3. Заверните тело метода main в try-catch и обработайте исключение InterruptOperationException.
Попрощайтесь с пользователем в блоке catch используя ConsoleHelper.

Пробовал сравнивать в п.1.1 и большие и маленькие буквы, с trim и без. Расставил везде, где может проскочить InterruptOperationException throws. Приниматься задание не хочет.

CahsMachine
public class CashMachine
{
    public static void main(String[] args)
    {
        Locale.setDefault(Locale.ENGLISH);
        try {
            Operation operation = null;

            do {
                operation = ConsoleHelper.askOperation();
                CommandExecutor.execute(operation);
            } while (operation != Operation.EXIT);

        } catch (InterruptOperationException e) {
            ConsoleHelper.writeMessage("Bye");
        }
    }
}


ConsoleHelper
public static String readString() throws InterruptOperationException{
        String line = null;

        try {
            line = reader.readLine();
            if ("EXIT".equalsIgnoreCase(line))
                throw new InterruptOperationException();
        } catch (IOException e) {

        }
        return line;
    }


ExitCommand
class ExitCommand implements Command {
    @Override
    public void execute() throws InterruptOperationException {
        ConsoleHelper.writeMessage("Are you sure want to quit? (y,n):");
        String answer;

        answer = ConsoleHelper.readString();
        if ("y".equalsIgnoreCase(answer.trim())){
            ConsoleHelper.writeMessage("Bye");
        }
        else if ("n".equalsIgnoreCase(answer.trim())){
            CommandExecutor.execute(ConsoleHelper.askOperation());
        }
    }
}