Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions src/main/java/Calculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import core.Communicator;
import exceptions.PersonsAboveZeroException;
import exceptions.PersonsOnlyException;
import exceptions.PersonsZeroException;
import models.Good;
import services.GoodsReadIterator;
import utils.Consts;

import java.util.ArrayList;

public class Calculator {
private final Communicator communicator;
private final GoodsReadIterator iterator;
private final ArrayList<Good> goods;
private final int personsQuantity;
private Calculator(Communicator communicator, int quantity){
this.communicator = communicator;
this.iterator = new GoodsReadIterator(this.communicator);
this.personsQuantity = quantity;
goods = new ArrayList<>();
}

public static Calculator createInstance(int quantity, Communicator communicator) {
if(quantity == 1) {
throw new PersonsOnlyException(Consts.ONLYPERSON_MESSAGE);
} else if (quantity == 0) {
throw new PersonsZeroException(Consts.ZEROPERSONS_MESSAGE);
} else if (quantity < 0) {
throw new PersonsAboveZeroException(Consts.LOWPERSONS_MESSAGE);
}
return new Calculator(communicator, quantity);
}

public void readGoods() {
do {
var good = iterator.next();
goods.add(good);
communicator.showNotification(Consts.ADD_SUCCESS_PROMT);
} while(iterator.hasNext());
}

public ArrayList<Good> getGoods() {
return goods;
}

public double totalPrice() {
return getGoods().stream().mapToDouble(Good::getPrice).sum();
}

public void printGoods() {
communicator.showNotification(Consts.ENTER_COMPLETE_PROMT);
for(var good: getGoods()) {
communicator.showNotification(good.toString());
}
var sharedPrice = totalPrice() / personsQuantity;
communicator.showNotification(String.format("Общий счет %.2f", totalPrice()));
communicator.showNotification(String.format("На каждого из %d человек по %.2f", personsQuantity, sharedPrice));
}
}
18 changes: 17 additions & 1 deletion src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import services.ConsoleCommunicator;
import utils.Consts;

public class Main {
private static final String TEMPLATE
= "\u001B[31mОшибка: %s. Перезапустите программу и повторите ввод.";
public static void main(String[] args) {
System.out.println("Hello world!");
var communicator = new ConsoleCommunicator();
try {
var persons = communicator.readInteger(Consts.ENTER_PERSONS_PROMT);
var calculator = Calculator.createInstance(persons, communicator);
calculator.readGoods();
calculator.printGoods();
} catch (RuntimeException e){
communicator
.showNotification(
String.format(TEMPLATE, e.getMessage()));
System.out.print("\u001B[0m");
}

}
}
11 changes: 11 additions & 0 deletions src/main/java/core/Communicator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package core;

import java.util.function.Predicate;

public interface Communicator {
void showNotification(String message);
String readString(String promt);
Double readDouble(String promt);
int readInteger(String promt);
boolean readBoolean(String promt, Predicate<String> pridicate);
}
7 changes: 7 additions & 0 deletions src/main/java/exceptions/PersonsAboveZeroException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package exceptions;

public class PersonsAboveZeroException extends PersonstQuantityException {
public PersonsAboveZeroException(String message) {
super(message);
}
}
7 changes: 7 additions & 0 deletions src/main/java/exceptions/PersonsOnlyException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package exceptions;

public class PersonsOnlyException extends PersonstQuantityException{
public PersonsOnlyException(String message) {
super(message);
}
}
7 changes: 7 additions & 0 deletions src/main/java/exceptions/PersonsZeroException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package exceptions;

public class PersonsZeroException extends PersonstQuantityException{
public PersonsZeroException(String message) {
super(message);
}
}
7 changes: 7 additions & 0 deletions src/main/java/exceptions/PersonstQuantityException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package exceptions;

class PersonstQuantityException extends RuntimeException {
public PersonstQuantityException(String message) {
super(message);
}
}
9 changes: 9 additions & 0 deletions src/main/java/exceptions/PriceInputException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package exceptions;

import utils.Consts;

public class PriceInputException extends RuntimeException {
public PriceInputException() {
super(Consts.INCORRECT_PROMT);
}
}
36 changes: 36 additions & 0 deletions src/main/java/models/Good.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package models;

import java.util.Objects;

import static utils.Currency.getCurencyString;

public class Good {
private final String name;
private final double price;
public Good(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}

public double getPrice() {
return price;
}
@Override
public String toString() {
return String.format("%s: %.2f %s", name, price, getCurencyString(getPrice()));
}
@Override
public boolean equals(Object o) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не вижу чтобы они сравнивались, зачем тогда equals?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот это выражение в тесте assertThat(calculator.getGoods()).hasSameElementsAs(goods) не будет работать. Там через equals сравнение идет.

if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Good good = (Good) o;
return Double.compare(good.price, price) == 0 && Objects.equals(name, good.name);
}
@Override
public int hashCode() {
return Objects.hash(name, price);
}
}
47 changes: 47 additions & 0 deletions src/main/java/services/ConsoleCommunicator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package services;

import core.Communicator;
import utils.Consts;

import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.function.Predicate;

public class ConsoleCommunicator implements Communicator {
@Override
public void showNotification(String message) {
System.out.println(message);
}
@Override
public String readString(String promt) {
System.out.println(promt);
var scanner = new Scanner(System.in);
return scanner.next();
}
@Override
public Double readDouble(String promt) {
var scanner = new Scanner(System.in);
System.out.println(promt);
if(scanner.hasNextDouble()) {
return scanner.nextDouble();
}
throw new InputMismatchException(Consts.DOUBLE_INCORRECT_PROMT);
}
@Override
public int readInteger(String promt) {
var scanner = new Scanner(System.in);
System.out.println(promt);
if(scanner.hasNextBigInteger()) {
return scanner.nextInt();
}
throw new InputMismatchException(Consts.INTEGER_INCORRECT_PROMT);
}
@Override
public boolean readBoolean(String promt, Predicate<String> pridicate) {
var scanner = new Scanner(System.in);
System.out.println(promt);
var input = scanner.next();
return pridicate.test(input);
}
}

55 changes: 55 additions & 0 deletions src/main/java/services/GoodsReadIterator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package services;

import core.Communicator;
import exceptions.PriceInputException;
import models.Good;
import utils.Consts;

import java.util.InputMismatchException;
import java.util.Iterator;

public class GoodsReadIterator implements Iterator<Good> {

private final Communicator communicator;

public GoodsReadIterator(Communicator communicator) {
this.communicator = communicator;
}

private Good readNextGood() {
var priceInputCount = 0;
var goodName = communicator.readString(Consts.ENTER_GOODNAME_PROMT);
double price = -1.0;
while((price <= 0) && priceInputCount < Consts.MAX_RETRY_PROMTS) {
try {
price = communicator.readDouble(Consts.ENTER_PRICE_PROMT);
priceInputCount ++;
if(price < 0){
throw new InputMismatchException(Consts.LOWPRICE_MESSAGE);
}
} catch (InputMismatchException e) {
communicator.showNotification(
String.format(Consts.RED + "Ошибка ввода: %s. Повторите ввод" + Consts.RESET, e.getMessage()));
}
if(priceInputCount == Consts.MAX_RETRY_PROMTS) {
throw new PriceInputException();
}
}
return new Good(goodName, price);
}

@Override
public boolean hasNext() {
return communicator.readBoolean(Consts.FINAL_PROMT,
n -> !n.equalsIgnoreCase(Consts.FINAL_TEMPLATE));
}

@Override
public Good next() {
var good = readNextGood();
if(good == null) {
throw new PriceInputException();
}
return good;
}
}
21 changes: 21 additions & 0 deletions src/main/java/utils/Consts.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package utils;

public class Consts {
public static final String RESET = "\u001B[0m";
public static final String RED = "\u001B[31m";
public static final String ONLYPERSON_MESSAGE = "Покупетель только 1, нет смысла в калькуляторе";
public static final String LOWPERSONS_MESSAGE = "Количество покупателей не может быть меньше нуля";
public static final String LOWPRICE_MESSAGE = "Количество покупателей не может быть меньше нуля";
public static final String ZEROPERSONS_MESSAGE = "Количество покупателей не может быть равно нулю";
public static final String FINAL_PROMT = "Хотите добавить еще один товар? Для завершения введите завершить";
public static final String FINAL_TEMPLATE = "ЗАВЕРШИТЬ";
public static final String ENTER_GOODNAME_PROMT = "Введите название товара";
public static final String ENTER_PRICE_PROMT = "Введите цену товара";
public static final String INCORRECT_PROMT = "Введено некорректное значение";
public static final String INTEGER_INCORRECT_PROMT = String.format("%s, ожидалось целое число", INCORRECT_PROMT);
public static final String DOUBLE_INCORRECT_PROMT = String.format("%s, ожидалось вещественнное число", INCORRECT_PROMT);
public static final int MAX_RETRY_PROMTS = 3;
public static final String ENTER_PERSONS_PROMT = "Введите количество покупателей";
public static final String ADD_SUCCESS_PROMT = "Товар успешно добавлен";
public static final String ENTER_COMPLETE_PROMT = "Добавленные товары:\n";
}
16 changes: 16 additions & 0 deletions src/main/java/utils/Currency.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package utils;

public class Currency {
public static String getCurencyString(double price) {
var mainPart = (int)price;
var preLastDigit = mainPart % 100 / 10;
if (preLastDigit == 1) {
return "рублей";
}
return switch (mainPart % 10) {
case 1 -> "рубль";
case 2, 3, 4 -> "рубля";
default -> "рублей";
};
}
}
Loading