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
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,29 @@
# Пустой репозиторий для работы с Java кодом в Android Studio
# мы тут исходя из своих способностей городим консольное приложение кто во что гаразд (•◡•) /

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

😄

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Многие техники и практики при разработке программ приходят лишь с опытом. Для всех нас еще совсем недавно вызывало огромную головную боль вопрос "а нужно ли мне вытаскивать эту логику в отдельный метод?" или "а как правильно назвать эту переменную, чтобы всем было понятно?". Мы все с понимаем относимся к пути изучения разработки, т.к. все проходили примерно через одни и те же трудности)

количество костылей превышает норму ᕙ(^▿^-ᕙ)

Послание для моего ревьюера:
-Спасибо, тебе, за твои труды на поприще обучения, нас, не разумных, искусству кодинга
Я очень благодарен тебе!!!
Надеюсь, ты отнесешься лояльно, к тому, что я тут нагородил, знай, Я только еще учусь и очень стараюсь.
а нагородил я в меру своих способностей и знаний, при помощи знаний из практикума, сообщений в пачке,
наставлений старших товарисщей ну и, конечно же, великого имогучего поисковика

все методы я постарался разнести по разным классам, да, на твой взгляд, наверняка, все выглядит корряво
и убого, то что я написал в несколько строк, наверняка, можно было бы уложить в одну, но я постарался
если честно, во многом мне помогла и IDE, зачастую она подсказывала мне такие конструкции выражений,
до которых я бы сам не додумался, храни господи разработчиков ))

я постарался закомментировать максимально подробно, за время написания кода, я умудрился запороть ветку
main, в моем репозитории, эх пришлось форкнуть все заново.

но когда я второй раз начал писать код, то я стал видеть яснее, как должны выглядить отдельные компоненты
приложения и где и как можно сократить колличество строк и методов, хотя общую картину я увидел
только ближе к концу

я очень долго думал, в каком виде хранить массив товаров, исходя из тех знаний, что есть дали нам
на практикуме, так и хотелось использовать массивы, но читерить не интересно, и я воспользовался
подсказкой, сохранил все в строку. И этот метод мне не очень понравился, к сожалению, в такой реализации,
по крайней мере сейчас, я не смогу вызвать отдельный элемент, или найти что-то определенное в строке

Еще раз спасибо тебе, и прошу, дать коментарии по моему коду)

13 changes: 13 additions & 0 deletions src/main/java/Calculate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
public class Calculate { /*класс для хранения переменной и методов для подсчета*/
public static float priceToPay;


public static void splitTheBill(float totalBill, int howManyPersons) {
priceToPay = totalBill / howManyPersons;
}

public static void showBillPerPerson(float totalBill, int howManyPersons) {
splitTheBill(totalBill, howManyPersons);
System.out.println("Cумма к оплате для одного гостя: " + PriceFormatterToString.priceFormattingToString(priceToPay));
}
}
25 changes: 23 additions & 2 deletions src/main/java/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@

import static java.util.Locale.ROOT;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
Locale.setDefault(ROOT);
ProductList.productList = ""; /*инициализируем переменные, содержащиеся в соответствующих классах*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⏫ Лучше для классов ProductList, Calculate и UI создать объекты, а не хранить все данные в статических синглтонах. Обычно , если какой-то класс хранит данные, необходимые для работы программы, стоит создавать объекты этих классов, чтобы обеспечить алокацию (уничтожение) объектов и их данных из памяти, когда мы их уже не используем.
Если же класс содержит лишь функции, которые исполняют какое-то действие бех сохранения промежуточных значений, можно делать данные функции static.

В текущем спринте мы познакомились с мощной парадигмой программирования - ООП. Стоит воспользоваться принципами этой парадигмы, чтобы организовать работу программы

ProductList.totalProductPrice = 0f;
Calculate.priceToPay = 0f;
UI.howManyPerson = 0;
UI.minPersonForSplit = 2;
UI.minProductPrice = 0.01f;


System.out.print("Приветствую!!! программа предназначена для подсчета стоимости чека \nи разделение чека на двух и более персон\nввиде количество гостей: ");

UI.getPersonsCount();

System.out.println("Спасибо, Вы собираетесь разделить счет на " + UI.inputInt + " гостей");
System.out.print("Введите название продукта: ");
UI.makeProductList();
System.out.println("Добавленные товары: ");
ProductList.showProductList();
ProductList.showTotalProductListPrice();
Calculate.showBillPerPerson(ProductList.totalProductPrice, UI.inputInt);
System.out.println("Спасибо, что используете отечественное ПО\nДосвидания!!!");
}
}
46 changes: 46 additions & 0 deletions src/main/java/PriceFormatterToString.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import java.util.Locale;
import java.util.Scanner;

public class PriceFormatterToString { /*класс предназначен для работы с ценой, для формирования строки*/
public static int abbreviationDigit(float inputDigit, int howManyCharacters) { /* метод для получения нескольких последних целых знаков*/
int b = (int) inputDigit; // отбрасываем дробную часть переменной путем перевода в другой тип данных (int целые числа)
int d = 10; // пременная для отсечения количества знаков, чем больше нулей тем больше знаков останется
if (howManyCharacters > 1) { // проверяем, сколко знаков нам нужно, если О`дин, то не входим в цикл
for (int i = 1; i < howManyCharacters; i++) { // тут в цикле подготавливаем переменную для получения соответствующего колличества знаков, десятку
d = d * 10; // умножаем на десятку для увеличения количества нуле
}
}
return (b - (b / d) * d); //возвращаем обработанный аргумент, в виде целого числа, в количестве необходимых знаков
}

public static String priceFormattingToString(float price) {

short c = (short) abbreviationDigit(price, 2); // этим действием оставляем два последних знака для выбора соответствующего падежа


if (c == 11 || c == 12 || c == 13 || c == 14) { /*проверяем два последних знака на первое условие */
return String.format( "%.2f", price) + " рублей";
} else {
c = (short) abbreviationDigit(price, 1); /*оставляем один последний знак до запятой*/
switch (c) {
case 1:
return String.format( "%.2f", price) + " рубль "; /*проверяем на оставшиеся условия, формируя строку, для возврата*/
case 2, 3, 4:
return String.format( "%.2f", price) + " рубля";
case 0, 5, 6, 7, 8, 9:
return String.format( "%.2f", price) + " рублей";


}
}
return "error in <printNumberToString> method"; /*выводим сообщение в случае ошибки*/
}

public static Scanner dotToPointReplacing(Scanner input) { /*метод для замены запятой на точку*/
String str = input.nextLine();
str = str.replace(",", ".");
Scanner scanner = new Scanner(str);
return scanner;
}

}
35 changes: 35 additions & 0 deletions src/main/java/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import java.util.Locale;

public class Product { /*новый класс для переменных продукт, содержит в себе номер строки или ноиер по парадку, название и цену*/
static int productNumber;
static String productName;
static float productPrice;

Product(int number, String name, float price) { /*конструктор класса продукт*/
productNumber = number;
productName = name;
productPrice = price;
}

public static String getProductData(Product product, String whatToShow) { /*метод класса продукт, возвращает строку в зависимости аргумента,
на входе, получает переменную класса продукт и строку с названием
данных которую необходимо получить */

switch (whatToShow) {
case "number":
return String.valueOf(Product.productNumber);
case "name":
return Product.productName;
case "price":
return String.valueOf(Product.productPrice);
default:
return "<getProductData> method can`t show this data";

}
}

public static String saveProductToString(Product product) {
String productPriceWithRUB = PriceFormatterToString.priceFormattingToString(Float.parseFloat(getProductData(product, "price")));
return "# " + getProductData(product, "number") + " " + getProductData(product, "name") + " " + productPriceWithRUB + "\n";
}
}
18 changes: 18 additions & 0 deletions src/main/java/ProductList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
public class ProductList { /*класс для хранения списка продуктов, как по мне
*костыль, но в массивы мы не умеем ¯\_( ͡❛ ͜ʖ ͡❛)_/¯*/
public static String productList;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⏫ Решение хранить значения сразу в String тоже имеет иместо быть. Но каждый раз при добавлении нового продукта и конкатенции (соединении) строк происходит создание нового экземпляра String, что пораждает большое количество неиспользуемых объектов. Чтобы это исправить можно воспользоваться StringBuilder. Вот статья на JavaRush, о преимуществах StringBuilder и как его правильно использовать.

public static float totalProductPrice;
public static void writeToProductList(Product product) { /*тут пишем в строку отформатированные данные для сохранения в строку*/
productList = productList + Product.saveProductToString(product);
totalProductPrice = totalProductPrice + Float.parseFloat(Product.getProductData(product, "price"));
}

public static void showProductList() {
System.out.println(ProductList.productList); /*сием выводим в консоль список продуктов*/
}

public static void showTotalProductListPrice() { /*сием выводим в консоль общую сумму*/
System.out.println("Общая сумма к оплате: " + PriceFormatterToString.priceFormattingToString(ProductList.totalProductPrice));
}
}

139 changes: 139 additions & 0 deletions src/main/java/UI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import static java.lang.System.in;
import static java.util.Locale.ROOT;
import java.util.Scanner;
/*класс предназначен для хранения переменных, необходимых для взаимодействия программы и пользователя
* переменные инициализируются в классе Main
* также в классе хранятся методы взаимодействия программы с пользователем*/
public class UI {
public static int inputInt;
public static float inputFloat;
public static String inputStr;
public static int minPersonForSplit;
public static float minProductPrice;
public static int howManyPerson;

public static boolean readyToGo(Scanner input, String needVariableType) {/*метод, для получения разрешения на продолжения программы
в зависимости от от двух аргументов, введенной переменной и строки, включающая в себя необходимый ти переменной,
возвращает true или false, в ходе работы использует методы прооверки текущего класса*/
switch (needVariableType) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

👍 Очень крутая валидация на вводимые значения. Выглядит мощно

⏫ Единственное, делать needVariableType через String - плохая практика. Лучше применить тип с огранизенными количеством значенией - например enum class.

case "needInt":
return checkForIntAndMinPersons(input);
case "needFloat":
return checkForFloatAndMinProductPrice(input);
case "needStr":
return checkForStr(input);
default:
System.err.println("error in Ui class methods");
break;
}

return false;
}

/*методы проверки введенных данных с консоли, на требуемый тип данных, возвращает логическую переменную
* в ходе работы присваивает сооответствующим переменным класса соответствующие данные, методы, также
* включает в себя вывод ошибки, в случае не сооответсвия типу данных, требуемому*/
public static boolean checkForIntAndMinPersons(Scanner input) {
boolean a = input.hasNextInt();
if (a) {
int b = input.nextInt();
if (b == 1) {
System.err.print("На одного человека нет смысла делить\nповторите ввод: ");
return false;
}
if (b > UI.minPersonForSplit - 1) {
inputInt = b;
return true;
} else {
return errMsgIntPrint();
}


} else {
return errMsgIntPrint();
}
}

public static boolean checkForFloatAndMinProductPrice(Scanner input) {
input = PriceFormatterToString.dotToPointReplacing(input);
boolean a = input.hasNextFloat();
if (a) {
float b = input.nextFloat();
if (b > (UI.minProductPrice - UI.minProductPrice)) {
inputFloat = b;
return true;
}
} else {
return errMsgFloatPrint();//false
}
return errMsgFloatPrint();//false
}

public static boolean checkForStr(Scanner input) {
inputStr = input.nextLine();
return true;
}

public static boolean errMsgIntPrint() {

System.err.print("Введите целое число, больше единицы\nповторите ввод колличества гостей: ");
return false;
}

public static boolean errMsgFloatPrint() {
System.err.print("Введите дробное число, больше нуля\nи повторите попытку ввода стоимости продукта: ");
return false;
}

public static void getPersonsCount() {
boolean a;
do {
Scanner scanner = new Scanner(in);
a = UI.readyToGo(scanner, "needInt");

} while (!a);
}

public static boolean getOneProduct() {
boolean readProductName;
int i = 0;
do {
boolean readProductPrice;
i++;
Scanner scanner = new Scanner(in);
inputStr = scanner.nextLine();
inputStr = inputStr.trim();
inputStr = inputStr.toLowerCase(ROOT);
readProductName = inputStr.equals("завершить");
readProductPrice = readProductName;
if (!readProductPrice) {
getProductPrice();
Product product = new Product(i, inputStr, inputFloat);
ProductList.writeToProductList(product);
System.out.print("продукт и его стоимость успешно добавлены\n" +
"если вы хотите закончить добавление товара, то введите \"завершить\" или\nвведите название продукта: ");
}
} while (!readProductName);

return true;
}

public static void getProductPrice() {
boolean readProductPrice;
System.out.print("Введите стоимость продукта: ");
do {
Scanner scanner = new Scanner(in);
readProductPrice = checkForFloatAndMinProductPrice(scanner);
} while (!readProductPrice);
}

public static void makeProductList() {
boolean a;
do {
a = getOneProduct();
} while (!a);
}
}