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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# Пустой репозиторий для работы с Java кодом в Android Studio
Домашняя работа по спринту 2
67 changes: 67 additions & 0 deletions src/main/java/Calculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import java.util.ArrayList;
import java.util.Locale;
import java.util.Scanner;

public class Calculator {

ArrayList<Product> productList = new ArrayList<>();
double totalAmount;

public void getData() {
Scanner scanner = new Scanner(System.in).useLocale(Locale.ENGLISH);
// без этой строки не принимает значения вида "Тест 2". Вот только в Windows НЕ работает
// scanner.useDelimiter(System.lineSeparator());
// нужно так, что в linux, что в windows - привет особенностям реализации консоли ввода
scanner.useDelimiter("\n");
// scanner.useLocale(Locale.ENGLISH); //десятичная точка вместо запятой
System.out.println("Введите список товаров");
while (true) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Не стоит запускать бесконечный цикл прямо в конструкторе класса, лучше вынести это в отдельную функцию, например start(), а в конструкторе класса оставить только конфигурацию объекта и его полей

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

принято

System.out.println("Введите название товара или команду \"Завершить\" для окончания ввода");
String userInput = scanner.next().trim();
if (userInput.equalsIgnoreCase("завершить")) {
break;
} else if (userInput.isEmpty()) {
System.out.println("Вы не ввели название товара, попробуйте ещё раз");
continue;
} else {
Product product = new Product(userInput);
while (true) {
double price;
try {
System.out.println("Укажите стоимость товара в формате рубли.копейки (например, 11.00 или 14.15)");
price = scanner.nextDouble();
} catch (Exception e) {
System.out.println("Стоимость товара должна быть числом, попробуйте ещё раз");
scanner.next(); //без этой строки зациклится, нужно сменить строку
continue;
}
if (price <= 0) {
System.out.println("Стоимость товара должна быть положительной");
} else {
product.price = price;
productList.add(product);
PriceFormatter formatter = new PriceFormatter(product.price);
System.out.println("Товар " + product.name + " со стоимостью " + formatter.getFormattedPrice() + " успешно добавлен");
totalAmount += product.price;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

totalAmount можно не считать отдельно, так как возможна рассинхронизация. Для консистентности можно вычислять общую стоимость, пробежавшись по списку товаров в цикле и посчитав сумму всех price

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Не согласен, так как в ТЗ было:

При добавлении товара в калькулятор нужно считать текущую общую сумму всех товаров.

В изначальном варианте был именно отдельный цикл, но исправил после внимательного чтения ТЗ

break;
}
}
}
}
}

public Calculator() {

}

/**
* Список товаров
*/
public void printList() {
System.out.println("Добавленные товары:");
for (Product product: productList) {
PriceFormatter formatter = new PriceFormatter(product.price);
System.out.println("Товар \"" + product.name + "\" стоит " + formatter.getFormattedPrice());
}
}
}
35 changes: 34 additions & 1 deletion src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
import java.util.Scanner;

public class Main {
public static int peopleCnt;

public static void askPeopleCnt() {
Scanner scanner = new Scanner(System.in);

while (true) {
try {
System.out.println("На скольких человек необходимо разделить счёт?");
peopleCnt = scanner.nextInt();
} catch (Exception e) {
System.out.println("Принимается только числовой ввод, попробуйте ещё раз");
scanner.nextLine();
continue;
}
if (peopleCnt < 1) {
System.out.println("Если никого нет, то и делить нечего. Число участников должно быть > 1");
} else if (peopleCnt == 1) {
System.out.println("Если заказ делал один человек, то он и платит. Число участников должно быть > 1");
} else {
break;
}
}
}

public static void main(String[] args) {
System.out.println("Hello world!");
System.out.println("Вас приветствует калькулятор счёта");
askPeopleCnt();
System.out.println("Данные приняты, делим счёт на "+peopleCnt+" человек(а)");
Calculator calc = new Calculator();
calc.getData();
calc.printList();
PriceFormatter formatter = new PriceFormatter(calc.totalAmount / peopleCnt);
System.out.println("Каждый человек должен заплатить "+formatter.getFormattedPrice()+"\n");
System.out.println("Спасибо за использование калькулятора. Приходите ещё.");
}
}
34 changes: 34 additions & 0 deletions src/main/java/PriceFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import java.util.Locale;

public class PriceFormatter {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Можно функции в этом классе пометить ключевым словом static, чтобы не приходилось каждый раз создавать объект этого класса. Нужно будет ещё price добавить в качестве аргументов функций. Таким образом, можно будет не создавать инстанс класса, а сразу вызывать функции, например PriceFormatter.getFormattedPrice(price)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Изначально так и было, потом почему-то переделал на этот вариант.
Принято.

/**
* Стоимость, которую будем выводить красиво
*/
Double price;

PriceFormatter(Double price) {
this.price = price;
}
/**
* Форматирование стоимости
* @return String руб.коп
*/
public String getFormattedPrice() {
// https://stackoverflow.com/questions/13763700/java-string-format-numbers-with-localization
return String.format(Locale.ENGLISH, "%1$,.2f", price) + " " + getFormattedCurrency();
}

private String getFormattedCurrency() {
String currency = "рубль";
int intPrice = price.intValue();
int lastDigit = intPrice % 10;
if (intPrice == 1 || (intPrice > 20 && lastDigit == 1)) {
currency = "рубль";
} else if ((intPrice >= 2 && intPrice < 5) || (intPrice > 20 && lastDigit >= 2 && lastDigit < 5)) {
currency = "рубля";
} else if ((intPrice >= 5 && intPrice < 20) || lastDigit == 0 || lastDigit >= 5) {
currency = "рублей";
}
return currency;
}
}
14 changes: 14 additions & 0 deletions src/main/java/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
public class Product {
/**
* Стоимость товара
*/
double price;
/**
* Название товара
*/
String name;
Comment on lines +5 to +9

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Поля лучше делать final или private. В случае с private, чтобы изменить значение поля, принято писать функции-сеттеры

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

принято, в спешке забыл


public Product(String name) {
this.name = name;
}
}