Определить класс (или структуру данных при использовании процедурного подхода), описывающий покупку одного и того же штучного товара по одной и той же цене (в белорусских рублях) в течение одного месяца и содержащий сведения о дне покупки и количестве приобретенных единиц.
Допускаются еще три варианта покупок:
со скидкой, задаваемой процентом от стоимости;
со скидкой в цене (например, цена товара 5000 руб., скидка 300 руб.);
с надбавкой за транспортные расходы на доставку товара.
Создать консольное приложение, в котором последовательно выполнить следующие задания:
определить набор покупок различного вида (не менее 10);
вывести на консоль в табличном виде (можно без границ) набор покупок (полный состав атрибутов);
вычислить и вывести стоимость всех покупок;
отсортировать покупки по возрастанию дня покупки и вывести их на консоль;
определить, была ли покупка в десятый день месяца.
Требования:
Использовать объектно-ориентированный подход для описания покупок.
Массив или коллекцию покупок инициализировать в коде с помощью конструктора или метода. Как следствие, не использовать внешние источники данных: консоль (т.е. ввод с клавиатуры), файлы, СУБД, XML и т.п.
Приложение должно быть консольным. Не использовать графический интерфейс! Таким образом, приложение ничего не должно вводить, а только выводить результаты на консоль.
Предпочтения по выбору:
языка программирования: 1) Java; 2) C++; 3) другой ООП язык.
реализации сортировки и поиска: 1) интерфейс внешних библиотек; 2) собственный код.
Вопрос, является ли ниже приведенный код вменяемым решением?
Отдельно хочется заметить, что условием запрещено использование генератора случайных чисел
Код:
package by.epam.stat;
import java.util.ArrayList;
import java.util.List;
public class Statistic {
// цена товара
int cost = 0;
// общая сумма за товары
int totalPrice = 0;
// для выравнивания столбцов
int alignment=7;
// сообщение об ошибке
String NoCorrect="Некорректные данные!";
// список для хранения покупок
List<Purchase> ShoppingList= new ArrayList<Purchase>();;
// выводит наименование товара и его цену
public Statistic(String product, int price) {
System.out.println("Товар - " + product + "\nЦена - " + price + " руб.\n");
cost = price;
}
// вывод заголовков
public void header() {
String headerString="День";
headerString=formatOutString(headerString, alignment) + "Количество";
alignment+=12;
headerString=formatOutString(headerString, alignment) + "Скидка";
alignment+=15;
headerString=formatOutString(headerString, alignment) + "Доставка";
alignment+=15;
headerString=formatOutString(headerString, alignment) + "Сумма";
alignment=6;
System.out.println(headerString);
}
// дополняет строку прбелами до num элемента
private String formatOutString(String outString, int num) {
if (outString.length() < num)
while (outString.length() < num)
outString += " ";
return outString;
}
// список покупок
public void generateShoppingList() {
// заполнение данных о покупке
/* формат:
*
* ShoppingList.add(new Purchase (day, count, discount, delivery));
* day - день покупки
* count - количество товара
* discount - скидка, если передается int считается скидкой по сумме,
* если double - скидкой в процентах
* delivery - стоимость доставки
*/
ShoppingList.clear();
ShoppingList.add(new Purchase(13, 9, 150000, 0));
ShoppingList.add(new Purchase(10, 3, 10000, 0));
ShoppingList.add(new Purchase(15, 5, 0.1, 15000));
ShoppingList.add(new Purchase(7, 2, 0.15, 20000));
ShoppingList.add(new Purchase(8, 8, 1.2, 0));
ShoppingList.add(new Purchase(2, 4, 0.03, 100000));
ShoppingList.add(new Purchase(-4, 10, 0.08, 11000));
ShoppingList.add(new Purchase(11, 2, 30000, 0));
ShoppingList.add(new Purchase(22, 3, 0.9, 80000));
ShoppingList.add(new Purchase(21, 5, 200000, 0));
ShoppingList.add(new Purchase(27, 7, 0.25, 4000));
// показать заголовки
header();
// вывод списка покупок
for (int i = 0; i < ShoppingList.size(); i++)
System.out.println(ShoppingList.get(i).getOutputString());
System.out.println("\nОбщая сумма покупок - "+totalPrice+" руб.");
System.out.println("\nПосле сортировки:\n");
// удаление некорректных данных в случае их наличия
for (int i = 0; i < ShoppingList.size(); i++)
if (ShoppingList.get(i).getOutputString().equals(NoCorrect))
ShoppingList.remove(i);
// сортировка по возрастанию дня покупки методом исключения минимального элемента
for (int i = 0; i < ShoppingList.size() - 1; i++)
for (int j = i + 1; j < ShoppingList.size(); j++)
if (ShoppingList.get(i).getDayPurchase() > ShoppingList.get(j).getDayPurchase()) {
// копия покупки, стоящей не на своем месте
Purchase buf = ShoppingList.get(i);
//вставка нужного эдемента на место "неправильного" и его последуещее удаление
ShoppingList.add(i, ShoppingList.get(j));
ShoppingList.remove(i + 1);
// вставка копии "неправильного" элемента на старое место "правильного" и удаление последнего
ShoppingList.add(j, buf);
ShoppingList.remove(j + 1);
}
// показать заголовки
header();
// вывод отсортированного списка
for (int i = 0; i < ShoppingList.size(); i++)
System.out.println(ShoppingList.get(i).getOutputString());
// проверка покупки в 10-ый день
int controlDay = 10;
boolean buy = false;
for (int i = 0; i < ShoppingList.size(); i++)
if (ShoppingList.get(i).getDayPurchase() == controlDay)
buy = true;
if (buy)
System.out.println("\nПокупка в " + controlDay + "-ый день произведена");
else
System.out.println("\nПокупка в " + controlDay + "-ый день не совершалась");
}
// получение итоговой стоимости и увеличение общей суммы, перегружена
private int getFinalCost(int count, int discount, int delivery) {
totalPrice+=cost*count-discount+delivery;
return cost*count-discount+delivery;
}
private int getFinalCost(int count, double discount, int delivery) {
totalPrice+=(int) (cost*count*(1-discount)+delivery);
return (int) (cost*count*(1-discount)+delivery);
}
public static void main(String[] args) {
Statistic statOfMonth = new Statistic("Телефон", 200000);
statOfMonth.generateShoppingList();
}
// класс для хранения инофрмации о покупке
public class Purchase {
int numDay=0;
String outputString="";
public Purchase(int day, int count, int discountCash, int delivery) {
if (isCorrect(day, count, discountCash, delivery)) {
numDay = day;
outputString += day;
// выравнивание после дня
outputString = formatOutString(outputString, alignment) + count;
alignment += 11;
// выравнивание после количества
outputString = formatOutString(outputString, alignment)
+ discountCash + " руб.";
alignment += 15;
// выравнивание после скидки
outputString = formatOutString(outputString, alignment)
+ delivery + " руб.";
alignment += 15;
int sum = getFinalCost(count, discountCash, delivery);
// выравнивание после доставки
outputString = formatOutString(outputString, alignment) + sum
+ " руб.";
alignment = 7;
} else
outputString = NoCorrect;
}
public Purchase(int day, int count, double discountPercent, int delivery) {
if (isCorrect(day, count, discountPercent, delivery)) {
numDay = day;
outputString += day;
// выравнивание после дня
outputString = formatOutString(outputString, alignment) + count;
alignment += 11;
// выравнивание после количества
outputString = formatOutString(outputString, alignment)
+ discountPercent * 100 + " %";
alignment += 15;
// выравнивание после скидки
outputString = formatOutString(outputString, alignment)
+ delivery + " руб.";
alignment += 15;
int sum = getFinalCost(count, discountPercent, delivery);
// выравнивание после доставки
outputString = formatOutString(outputString, alignment) + sum
+ " руб.";
alignment = 7;
} else
outputString = NoCorrect;
}
public String getOutputString() {
return outputString;
}
public int getDayPurchase () {
return numDay;
}
// проверка корректности данных, перегружена
private boolean isCorrect(int day, int count, double discountPercent, int delivery) {
if (day>=1 && day<=31 && count>0 && delivery>=0 && discountPercent>=0 && discountPercent<1)
return true;
else return false;
}
private boolean isCorrect(int day, int count, int discountCash, int delivery) {
if (day>=1 && day<=31 && count>0 && delivery>=0 && discountCash<cost && discountCash>=0)
return true;
else return false;
}
}
}
p. s. лично меня смущают перегруженные функции, но не смог найти более элегантного решения