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
35 changes: 35 additions & 0 deletions src/main/java/Calculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import java.util.ArrayList;

public class Calculator {
private final int personsCount;
private final ArrayList<Product> products = new ArrayList<>();

private float totalSum = 0;

Calculator(int count) {
personsCount = count;
}

public void add(Product product) {
products.add(product);

totalSum += product.price;

System.out.println("Товар успешно добавлен.");
}

public void showAllProducts() {
System.out.println("Добавленные товары:");

for (Product product : products) {
System.out.println(product.toString());
}
}

public void showSumByPerson() {
System.out.printf(
"Каждый человек должен заплатить %s.",
PriceFormatter.getHumanizedPrice(totalSum / personsCount)
);
}
}
47 changes: 45 additions & 2 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@

public class Main {
private static final int MIN_PEOPLE_COUNT = 2;
private static final String FINISH_COMMAND = "Завершить";

static int readPersonsCount() {
int personsCount;

while (true) {
personsCount = TerminalReader.readInt(
String.format(
"На скольких человек разделить счет ? (значение должно быть >=%d)",
MIN_PEOPLE_COUNT
)
Comment on lines +10 to +13

Choose a reason for hiding this comment

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

Круто, что ты везде по максимуму используешь форматирование строк через String.format, т.к. это работает быстрее и требует меньше памяти, чем та же конкатенация строк. Есть ещё класс StringBuilder, который работает ещё быстрее чем String.format, можешь почитать о нём, а может и применишь и в этой практической работе

Copy link
Owner Author

Choose a reason for hiding this comment

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

спасибо, почитаю

);

if (personsCount < MIN_PEOPLE_COUNT) {
System.out.printf(
"Значение должно быть >=%d !%n",
MIN_PEOPLE_COUNT
);
} else {
break;
}
}

return personsCount;
}

public static void main(String[] args) {
System.out.println("Hello world!");
int personsCount = readPersonsCount();

Calculator calculator = new Calculator(personsCount);

while (true) {
Product product = Product.read();

calculator.add(product);

String command = TerminalReader.readString("Хотите добавить еще товар ? Если нет, введите \"завершить\".");

if (command.equalsIgnoreCase(FINISH_COMMAND)) {
break;
}
}

calculator.showAllProducts();
calculator.showSumByPerson();
}
}
28 changes: 28 additions & 0 deletions src/main/java/PriceFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
public class PriceFormatter {
public static String getHumanizedPrice(float price) {
String rounded = String.format("%.2f", price).replace(',', '.');

// передаем уже округленное значение для гарантии консистентности
return String.format("%s %s", rounded, getPriceSpelling(Float.parseFloat(rounded)));
Copy link
Owner Author

Choose a reason for hiding this comment

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

благодаря этому финту, если мы в эту функцию передадим 1.9999, то на выходе будет строка "2.00 рубля", а не "2.00 рубль"

}

private static String getPriceSpelling(float price) {
int roundedPrice = (int) price;
int preLastDigit = roundedPrice % 100 / 10;

if (preLastDigit == 1) {
return "рублей";
}

switch (roundedPrice % 10) {
case 1:
return "рубль";
case 2:
case 3:
case 4:
return "рубля";
default:
return "рублей";
}
}
}
31 changes: 31 additions & 0 deletions src/main/java/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
public class Product {
String name;
float price;

Product(String productName, float productPrice) {
name = productName;
price = productPrice;
}

static Product read() {
String name = TerminalReader.readString("Введите название товара:");
float price;

while (true) {
price = TerminalReader.readFloat("Введите цену товара:");

if (price >= 0) {
break;
}

System.out.println("Цена не должна быть отрицательным числом!");
}

return new Product(name, price);
}

@Override
public String toString() {
return String.format("– %s: %s", name, PriceFormatter.getHumanizedPrice(price));
}
}
49 changes: 49 additions & 0 deletions src/main/java/TerminalReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import java.util.Scanner;

public class TerminalReader {
final static private Scanner scanner = new Scanner(System.in);
public static String readString(String message) {

Choose a reason for hiding this comment

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

Эта функция имеет модификатор public, а другие две функции ниже - нет, хотя логично было бы предположить, что эти три функции должны иметь один и тот же модификатор доступа (public)

Copy link
Owner Author

Choose a reason for hiding this comment

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

по-умолчанию проде они public и так идут, да ?

есть ли смысл явно прописывать ?

Copy link

@ArturNurtdinov ArturNurtdinov Feb 12, 2024

Choose a reason for hiding this comment

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

По умолчанию в джаве они package-private, то есть видимость на уровне пакета
В Котлине по умолчанию публичные, но есть случаи (например когда пишешь библиотеку) когда нужно прописывать явно

System.out.println(message);

return scanner.next();
}

public static float readFloat(String message) {
float resultValue;

while (true) {
System.out.println(message);

String stringValue = scanner.next();

try {
resultValue = Float.parseFloat(stringValue);
break;
} catch (NumberFormatException e) {
System.out.printf("\"%s\" не является числом%n", stringValue);
}
}

return resultValue;
}

public static int readInt(String message) {
int resultValue;

while (true) {
System.out.println(message);

String stringValue = scanner.next();

try {
resultValue = Integer.parseInt(stringValue);
break;
} catch (NumberFormatException e) {
System.out.printf("\"%s\" не является числом%n", stringValue);
}

}

return resultValue;
}
}