diff --git a/.gitignore b/.gitignore index 8f242ff..38a19dd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ # Mobile Tools for Java (J2ME) .mtj.tmp/ +# vim swap files +*.swp + # Package Files # *.jar !gradle-wrapper.jar diff --git a/.gradle/6.3/executionHistory/executionHistory.lock b/.gradle/6.3/executionHistory/executionHistory.lock deleted file mode 100644 index a7604be..0000000 Binary files a/.gradle/6.3/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/6.3/fileChanges/last-build.bin b/.gradle/6.3/fileChanges/last-build.bin deleted file mode 100644 index f76dd23..0000000 Binary files a/.gradle/6.3/fileChanges/last-build.bin and /dev/null differ diff --git a/.gradle/6.3/fileHashes/fileHashes.lock b/.gradle/6.3/fileHashes/fileHashes.lock deleted file mode 100644 index 2b22044..0000000 Binary files a/.gradle/6.3/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/6.3/gc.properties b/.gradle/6.3/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/6.5/executionHistory/executionHistory.bin b/.gradle/6.5/executionHistory/executionHistory.bin deleted file mode 100644 index ca60313..0000000 Binary files a/.gradle/6.5/executionHistory/executionHistory.bin and /dev/null differ diff --git a/.gradle/6.5/executionHistory/executionHistory.lock b/.gradle/6.5/executionHistory/executionHistory.lock deleted file mode 100644 index 7ae781a..0000000 Binary files a/.gradle/6.5/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/6.5/fileChanges/last-build.bin b/.gradle/6.5/fileChanges/last-build.bin deleted file mode 100644 index f76dd23..0000000 Binary files a/.gradle/6.5/fileChanges/last-build.bin and /dev/null differ diff --git a/.gradle/6.5/fileHashes/fileHashes.bin b/.gradle/6.5/fileHashes/fileHashes.bin deleted file mode 100644 index adb536e..0000000 Binary files a/.gradle/6.5/fileHashes/fileHashes.bin and /dev/null differ diff --git a/.gradle/6.5/fileHashes/fileHashes.lock b/.gradle/6.5/fileHashes/fileHashes.lock deleted file mode 100644 index b89035b..0000000 Binary files a/.gradle/6.5/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/6.5/gc.properties b/.gradle/6.5/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock deleted file mode 100644 index 125640c..0000000 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and /dev/null differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index b774acd..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Thu Oct 08 23:16:29 MSK 2020 -gradle.version=6.3 diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock deleted file mode 100644 index 2cf264e..0000000 Binary files a/.gradle/checksums/checksums.lock and /dev/null differ diff --git a/.gradle/vcs-1/gc.properties b/.gradle/vcs-1/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index c8b5c9a..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 87ca0fc..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index fdc392f..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index b0ec460..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index c29a8be..2aa9b50 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,9 @@ -# Примеры для курса "Разработчик Java" в OTUS +Написать эмулятор АТМ (банкомата). -Группа 2020-09 +Объект класса АТМ должен уметь: -### Преподаватели -Сергей Петрелевич
-Стрекалов Павел
-Александр Оруджев
-Вячеслав Лапин
-Виталий Куценко
-Дмитрий Коган +принимать банкноты разных номиналов (на каждый номинал должна быть своя ячейка) +выдавать запрошенную сумму минимальным количеством банкнот или ошибку если сумму нельзя выдать Это задание не на алгоритмы, а на проектирование. Поэтому оптимизировать выдачу не надо. +выдавать сумму остатка денежных средств +В этом задании больше думайте об архитектуре приложения. Не отвлекайтесь на создание таких объектов как: пользователь, авторизация, клавиатура, дисплей, UI (консольный, Web, Swing), валюта, счет, карта, т.д. Все это не только не нужно, но и вредно! -Студент: -Kashapov Renat (Кашапов Ренат)
-renat.kashapov@gmail.com \ No newline at end of file diff --git a/hw06-ATM/build.gradle b/hw06-ATM/build.gradle new file mode 100644 index 0000000..55b2f50 --- /dev/null +++ b/hw06-ATM/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'java' + id 'application' +} + +group 'ru.otus' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' +} + +test { + useJUnitPlatform() +} + +mainClassName = 'atm.Starter' \ No newline at end of file diff --git a/hw06-ATM/src/main/java/atm/Nominal.java b/hw06-ATM/src/main/java/atm/Nominal.java new file mode 100644 index 0000000..9483280 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/Nominal.java @@ -0,0 +1,29 @@ +package atm; + +public enum Nominal { + ONE_HUNDRED( 100 ), + TWO_HUNDREDS( 200 ), + FIVE_HUNDRED( 500 ), + ONE_THOUSAND( 1000 ), + TWO_THOUSANDS( 2000 ), + FIVE_THOUSANDS( 5000 ); + + private Integer nominal; + + Nominal( Integer nominal ) { + this.nominal = nominal; + } + + public Integer getNominal() { + return nominal; + } + + public static Nominal getNominalFromInt( Integer value ) { + if ( value == null ) return null; + for ( Nominal nominal : values() ) { + if ( nominal.nominal.equals( value ) ) return nominal; + } + return null; + } +} + diff --git a/hw06-ATM/src/main/java/atm/Starter.java b/hw06-ATM/src/main/java/atm/Starter.java new file mode 100644 index 0000000..59744a0 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/Starter.java @@ -0,0 +1,64 @@ +package atm; + +import atm.atm.ATMService; +import atm.atm.impl.ATMImpl; +import atm.atm.impl.ATMServiceImpl; +import java.util.List; +import java.util.Scanner; + +public class Starter { + private ATMImpl atm; + + public static void main(String args[]) { + Starter starter = new Starter(); + starter.atm = ATMImpl.ATMImplBuilder.build(); + String name = "User"; + System.out.println("Hello, my dear friend. What's your name?"); + Scanner scanner = new Scanner(System.in); + Scanner stringScanner; + name = scanner.nextLine(); + System.out.println("Hello " + name + "! What's your command? (add, get, rest, exit)"); + String operation = scanner.nextLine(); + while (!operation.equalsIgnoreCase("exit")) { + switch (operation.toLowerCase()) { + case "add": + System.out.println("What nominal?"); + String nominalsString = scanner.nextLine(); + stringScanner = new Scanner(nominalsString); + Integer value; + while (stringScanner.hasNextInt()) { + value = stringScanner.nextInt(); + Nominal nominal = Nominal.getNominalFromInt(value); + if (nominal != null) { + starter.atm.putCash(nominal); + System.out.println("Success " + nominal.getNominal()); + } else { + System.out.println(value + "? Was it?"); + } + } + break; + case "get": + System.out.println("How much? Enter sum"); + String sumString = scanner.nextLine(); + stringScanner = new Scanner(sumString); + value = stringScanner.nextInt(); + List cash = starter.atm.getCash(value); + System.out.print("Cash included:"); + for (Nominal nominal:cash){ + System.out.print(" " + nominal.getNominal()); + } + System.out.println(""); + break; + case "rest": + ATMService atmService = new ATMServiceImpl(starter.atm); + System.out.println("Balance is " + atmService.getBalance()); + break; + default: + System.out.println("Incorrect command"); + } + + System.out.println(" What's your next command? (add, get, rest, exit)"); + operation = scanner.nextLine(); + } + } +} \ No newline at end of file diff --git a/hw06-ATM/src/main/java/atm/atm/ATM.java b/hw06-ATM/src/main/java/atm/atm/ATM.java new file mode 100644 index 0000000..bb169e5 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/atm/ATM.java @@ -0,0 +1,13 @@ +package atm.atm; + +import atm.Nominal; +import atm.cell.Cell; + +import java.util.List; + +public interface ATM { + boolean putCash( Nominal cash); + List getCash(Integer sum); + List getAtmStorage(); +} + diff --git a/hw06-ATM/src/main/java/atm/atm/ATMService.java b/hw06-ATM/src/main/java/atm/atm/ATMService.java new file mode 100644 index 0000000..07aa917 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/atm/ATMService.java @@ -0,0 +1,9 @@ +package atm.atm; + +import atm.cell.Cell; +import java.util.List; + +public interface ATMService { + + Integer getBalance(); +} diff --git a/hw06-ATM/src/main/java/atm/atm/impl/ATMImpl.java b/hw06-ATM/src/main/java/atm/atm/impl/ATMImpl.java new file mode 100644 index 0000000..bb48542 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/atm/impl/ATMImpl.java @@ -0,0 +1,94 @@ +package atm.atm.impl; + +import atm.Nominal; +import atm.atm.ATM; +import atm.cell.Cell; +import atm.cell.impl.CellImpl; +import java.util.*; +import java.util.stream.Collectors; + +public class ATMImpl implements ATM { + private List atmStorage; + + private ATMImpl() { + + this.atmStorage = new ArrayList<>(); + for (Nominal nominal : Nominal.values()) { + this.atmStorage.add(new CellImpl(nominal, 5)); + } + } + + public List getAtmStorage(){ + return new ArrayList<>(this.atmStorage); + } + + @Override + public boolean putCash(Nominal cash) { + Cell curCell = null; + for (Cell cellNominalEntry : atmStorage) { + if (cellNominalEntry.getNominal() == cash && cellNominalEntry.getCount() < CellImpl.MAX_COUNT) { + cellNominalEntry.put(1); + return true; + } + } + return false; + } + + @Override + public List getCash(Integer sum) { + if (sum % 100 != 0) { + throw new IllegalArgumentException("Введена некорректная сумма. Минимальная купюра - 100р."); + } + List outList = new ArrayList<>(); + List nominalList = new ArrayList<>(this.atmStorage.stream().map(Cell::getNominal).collect(Collectors.toList())); + nominalList.sort(Comparator.reverseOrder()); + Map checkMap = new HashMap<>(); + for (Nominal nominal : nominalList) { + Integer mustGive = sum / nominal.getNominal(); + sum = sum % nominal.getNominal(); + Integer canGive = 0; + for (Cell cell : this.atmStorage) + if (cell.getNominal() == nominal) + canGive += cell.getCount(); + if (canGive < mustGive) { + sum += (mustGive - canGive) * nominal.getNominal(); + checkMap.put(nominal, canGive); + } else { + if (!checkMap.containsKey(nominal)) + checkMap.put(nominal, mustGive); + } + } + if (sum != 0) { + int iHave = 0; + for (Nominal key : checkMap.keySet()) { + iHave += key.getNominal() * checkMap.get(key); + } + throw new IllegalArgumentException("Невозможно выдать запрашиваемую сумму имеющимися купюрами, максимально возможная сумма: " + iHave); + } else { + for (Nominal key : checkMap.keySet()) + addBanknotes(checkMap.get(key), key, outList); + } + return outList; + } + + private void addBanknotes(Integer number, Nominal nominal, List outList) { + for (int i = 0; i < number; i++) { + Cell minCountCell = null; + int minCount = Cell.MAX_COUNT; + outList.add(nominal); + for (Cell cell : this.atmStorage) + if (cell.getNominal() == nominal && cell.getCount() > 0 && cell.getCount() <= minCount) { + minCount = cell.getCount(); + minCountCell = cell; + } + minCountCell.get(1); + } + } + + public static class ATMImplBuilder { + public static ATMImpl build() { + ATMImpl atm = new ATMImpl(); + return atm; + } + } +} \ No newline at end of file diff --git a/hw06-ATM/src/main/java/atm/atm/impl/ATMServiceImpl.java b/hw06-ATM/src/main/java/atm/atm/impl/ATMServiceImpl.java new file mode 100644 index 0000000..5631076 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/atm/impl/ATMServiceImpl.java @@ -0,0 +1,22 @@ +package atm.atm.impl; + +import atm.atm.ATM; +import atm.atm.ATMService; +import atm.cell.Cell; + +public class ATMServiceImpl implements ATMService { + + private ATM atm; + + public ATMServiceImpl(ATM atm){ + this.atm = atm; + } + @Override + public Integer getBalance() { + Integer balance = 0; + for (Cell cell : atm.getAtmStorage()) { + balance += cell.getCount() * cell.getNominal().getNominal(); + } + return balance; + } +} diff --git a/hw06-ATM/src/main/java/atm/cell/Cell.java b/hw06-ATM/src/main/java/atm/cell/Cell.java new file mode 100644 index 0000000..adfda3a --- /dev/null +++ b/hw06-ATM/src/main/java/atm/cell/Cell.java @@ -0,0 +1,13 @@ +package atm.cell; +import atm.Nominal; + +public interface Cell { + public static final Integer MAX_CAPACITY = 10; + public static final Integer MAX_COUNT = 100; + + public void put( Integer count ); + public Integer get( Integer count ); + public Integer getCount(); + public Nominal getNominal(); + public Integer getBalance(); +} diff --git a/hw06-ATM/src/main/java/atm/cell/impl/CellImpl.java b/hw06-ATM/src/main/java/atm/cell/impl/CellImpl.java new file mode 100644 index 0000000..2e151e9 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/cell/impl/CellImpl.java @@ -0,0 +1,46 @@ +package atm.cell.impl; + +import atm.Nominal; +import atm.exceptions.CellIsFullException; + +public class CellImpl implements atm.cell.Cell { + private final Nominal nominal; + private Integer count; + + public CellImpl( Nominal cellNominal, Integer cellCount ) { + this.nominal = cellNominal; + this.count = cellCount; //Initial load + } + + @Override + public void put( Integer count ) { + if (this.count + count > MAX_CAPACITY){ + throw new CellIsFullException(); + } + this.count += count; + } + + @Override + public Integer get( Integer count ) { + Integer toReturn = ( this.count >= count ) ? count : this.count; + this.count -= toReturn; + return toReturn; + } + + @Override + public Integer getCount() { + return this.count; + } + + @Override + public Nominal getNominal() { + return this.nominal; + } + + + @Override + public Integer getBalance() { + return nominal.getNominal()*count; + } +} + diff --git a/hw06-ATM/src/main/java/atm/exceptions/AtmException.java b/hw06-ATM/src/main/java/atm/exceptions/AtmException.java new file mode 100644 index 0000000..ad462a7 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/exceptions/AtmException.java @@ -0,0 +1,4 @@ +package atm.exceptions; + +public class AtmException extends RuntimeException { +} diff --git a/hw06-ATM/src/main/java/atm/exceptions/CellIsFullException.java b/hw06-ATM/src/main/java/atm/exceptions/CellIsFullException.java new file mode 100644 index 0000000..b461432 --- /dev/null +++ b/hw06-ATM/src/main/java/atm/exceptions/CellIsFullException.java @@ -0,0 +1,4 @@ +package atm.exceptions; + +public class CellIsFullException extends AtmException { +} diff --git a/settings.gradle b/settings.gradle index 9a32c0b..435bb60 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ rootProject.name = 'otus_hw' +include 'hw06-ATM' diff --git a/src/main/java/A.java b/src/main/java/A.java deleted file mode 100644 index 6be5562..0000000 --- a/src/main/java/A.java +++ /dev/null @@ -1,5 +0,0 @@ -public class A { - public static void main(String ... args){ - System.out.println("Hello, gradle + git!"); - } -}