• ,

task18.task1827 не проходит проверку_РЕШЕНО

Всем доброго дня. Задача task18.task1827. Условие:
Прайсы
CrUD для таблицы внутри файла.
Считать с консоли имя файла для операций CrUD.

Программа запускается со следующим набором параметров:
-c productName price quantity

Значения параметров:
где id — 8 символов.
productName — название товара, 30 chars (60 bytes).
price — цена, 8 символов.
quantity — количество, 4 символа.
-c — добавляет товар с заданными параметрами в конец файла, генерирует id самостоятельно, инкрементируя максимальный id, найденный в файле.

В файле данные хранятся в следующей последовательности (без разделяющих пробелов):
id productName price quantity

Данные дополнены пробелами до их длины.

Пример:
19846 Шорты пляжные синие 159.00 12
198478 Шорты пляжные черные с рисунко173.00 17
19847983Куртка для сноубордистов, разм10173.991234


Валидатор при проверке выдаёт не засчитывает один пункт:
CrUD_test

Перепробовал что смог, может кто сможет помочь. Чего хочет валидатор и почему формат новой чтроки прайса его не устраивает. Заранее спасибо. Код программы ниже.

package com.javarush.task.task18.task1827;

/* 
Прайсы
*/

import java.io.*;
import java.util.*;

public class Solution {
    static String fileName;
    final static byte idLength = 8,
            productNameLength = 38,
            priceLength = 46,
            quantityLength = 50;
    static List<String[]> prices = new ArrayList<>();
    {

    }

    public static void main(String[] args) throws Exception {
        readPrices();
        switch (args[0]) {
            case ("-c"):
                createPrice(args);
                break;
        }
    }

    static void enterFileName() throws IOException{
        BufferedReader bRead = new BufferedReader(new InputStreamReader(System.in));
        fileName = bRead.readLine();
        bRead.close();
    }

    public static void createPrice(String[] args) throws IOException{//добавляет в список прайсов новый прайс и запис. в файл
        prices.add(getNewPriceArr(args));
        BufferedWriter bWriter = null;

        try {
            bWriter = new BufferedWriter(new FileWriter(fileName));

            for (int i = 0, end = prices.size() - 1;i < end;i++){
                bWriter.write(getPriceLine(prices.get(i)));
                bWriter.newLine();
            }

            bWriter.write(getPriceLine(prices.get(prices.size() - 1)));

        } catch (IOException e) {
            throw new IOException("Exception when file write", e);
        } finally {
            if (bWriter != null) {
                try {
                    bWriter.close();
                }
                catch (IOException ignore) {
                    /*NOP*/
                }
            }
        }
    }

    public static void readPrices() throws IOException{//загружает в карту содержимое файла
        enterFileName();
        BufferedReader bRead = null;
        String nextLine;

        try
        {
            bRead = new BufferedReader(new FileReader(fileName));
            while (bRead.ready())
            {
                nextLine = bRead.readLine();
                prices.add(new String[] {getID(nextLine), getProductName(nextLine), getPrice(nextLine), getQuantity(nextLine)});
            }
        } catch (FileNotFoundException e) {
            System.out.println("Exception when file found");
        } catch (IOException e) {
            throw new IOException("Exception when file read", e);
        } finally {
            if (bRead != null){
                try
                {
                    bRead.close();
                } catch (IOException ignore) {
                    /*NOP*/
                }
            }
        }
    }

    static String getID(String priceLine){//возвращает численное значение ID
        return priceLine.substring(0, idLength);
    }

    static String getProductName(String priceLine){//возвращает строку-название товара
        return priceLine.substring(idLength, productNameLength);
    }

    static String getPrice(String priceLine){//возвращает строку-цену товара
        return priceLine.substring(productNameLength, priceLength);
    }

    static String getQuantity(String priceLine){//возвращает строку-количество товара
        return priceLine.substring(priceLength);
    }

    static int getMaxID(){
        if (prices.size() == 0) {
            return 0;
        }
        Object[] idS = new Object[prices.size()];

        for (int i = 0, end = prices.size();i < end;i++){
            idS[i] = getIntID(prices.get(i)[0]);
        }

        Arrays.sort(idS);
        return (int)idS[idS.length - 1];
    }

    static String getNextID(){
        int nextID = getMaxID() + 1;
        String nextIDStr = Integer.toString(nextID);

        if (nextIDStr.length() < idLength) {
            for (int i = 0, end = idLength - nextIDStr.length();i < end;i++) {
                nextIDStr = nextIDStr + " ";
            }

            return nextIDStr;
        } else if (nextIDStr.length() > idLength) {
            return nextIDStr.substring(0, 8);
        }

        return nextIDStr;
    }

    static int getIntID(String stringID){
        return Integer.parseInt(stringID.split(" ")[0]);
    }

    static String[] getNewPriceArr(String[] args){//возвр массив [4] с занесенными параметрами
        return new String[]{getNextID(), getNewPriceProdName(args[1]), getNewPricePrice(args[2]), getNewPriceQuantity(args[3])};
    }

    static String getNewPriceProdName(String prodName){//возвращает адаптированное значение названия
        int prodNameSize = productNameLength - idLength;
        String newProdName = prodName;

        if (prodName.length() > prodNameSize) {
            newProdName = newProdName.substring(0, prodNameSize);
        } else if (prodName.length() < prodNameSize) {
            for (int i = 0, end = prodNameSize - prodName.length();i < end;i++) {
                newProdName = newProdName + " ";
            }
        }

        return newProdName;
    }

    static String getNewPricePrice(String price){//возвращает адаптированное значение цены
        int priceSize = priceLength - productNameLength;
        String newPrice = price;

        if (price.length() > priceSize) {
            newPrice = newPrice.substring(0, priceSize);
        } else if (price.length() < priceSize) {
            for (int i = 0, end = priceSize - price.length();i < end;i++) {
                newPrice = newPrice + " ";
            }
        }

        return newPrice;
    }

    static String getNewPriceQuantity(String quant){//возвращает адаптированное значение количества
        int quantSize = quantityLength - priceLength;
        String newQuant = quant;

        if (quant.length() > quantSize) {
            newQuant = newQuant.substring(0, quantSize);
        } else if (quant.length() < quantSize) {
            for (int i = 0, end = quantSize - quant.length();i < end;i++) {
                newQuant = newQuant + " ";
            }
        }

        return newQuant;
    }

    static String getPriceLine(String[] price){
        return price[0] + price[1] + price[2] + price[3];
    }
}

20 комментариев

AlexAV
Выложите что получается в файле…
Alvisid
Входные аргументы:
-c
"Сланцы Nike"
13.564
15


Если файл пуст, то запишет

1       Сланцы Nike                   13.564  15  


если в файле было:

19846   Шорты пляжные синие           159.00  12  
198478  Шорты пляжные черные с рисунко173.00  17  
19847983Куртка для сноубордистов, разм10173.991234


то становится:

19846   Шорты пляжные синие           159.00  12  
198478  Шорты пляжные черные с рисунко173.00  17  
19847983Куртка для сноубордистов, разм10173.991234
19847984Сланцы Nike                   13.564  15  


Если название превышает 30 символов:

-c
"Сланцы Nike с фиолетовыми завязками и перламутровыми пуговицами"
13.564
15


пустой файл:

1       Сланцы Nike с фиолетовыми завя13.564  15  


с тремя строками и наибольший ID не последний:

19846   Шорты пляжные синие           159.00  12  
19847843Шорты пляжные черные с рисунко173.00  17  
198479  Куртка для сноубордистов, разм10173.991234


в файл запишет:

19846   Шорты пляжные синие           159.00  12  
19847843Шорты пляжные черные с рисунко173.00  17  
198479  Куртка для сноубордистов, разм10173.991234
19847844Сланцы Nike с фиолетовыми завя13.564  15  
AlexSir
  • AlexSir
  • 0
  • Комментарий отредактирован 2017-02-10 14:32:24 пользователем AlexSir
Добрый день!
Очень сложный код и его ОООЧЕНЬ много для данной задачи. Можно упростить практически ВСЕ.
Зачем очень много массивов, и даже присутствует сортировка?
Это чисто мое мнение, и можешь к нему не прислушиваться, но знаю точно — за такой код накажут

Теперь по задаче и почему не принимается:
В задаче не сказано — пересоздавать файл, а «добавляет товар с заданными параметрами в конец файла» в этом и ошибка

у тебя вывод в файл:
19847991шорты ghj,t sdfad 987.123 0
19847992шорты ghj,t sdfad 987.123 0

А должно быть:
19847991шорты ghj,t sdfad 987.123 0 19847992шорты ghj,t sdfad 987.123 0
Alvisid
  • Alvisid
  • 0
  • Комментарий отредактирован 2017-02-10 16:27:46 пользователем Alvisid
Переписал прогу через формат:
import java.io.*;

public class Solution {
    static String stringForm = "%-8d%-30.30s%-8s%-4s";

    public static void main(String[] args) throws Exception {
        switch (args[0]) {
            case ("-c"):
                createPrice(args);
                break;
        }
    }

    public static void createPrice(String[] args) throws IOException{
        BufferedReader bRead = new BufferedReader(new InputStreamReader(System.in));
        String fileName = bRead.readLine();
        BufferedReader bufFileReader = new BufferedReader(new FileReader(fileName));
        BufferedWriter fileWriter = new BufferedWriter(new FileWriter(fileName, true));

        if (!bufFileReader.ready()){
            fileWriter.write(String.format(stringForm, 1, args[1], args[2], args[3]));
        } else {

            int maxId = Integer.parseInt(bufFileReader.readLine().substring(0, 8).replaceAll(" ", ""));
            int nextID;

            while (bufFileReader.ready()){
                nextID = Integer.parseInt(bufFileReader.readLine().substring(0, 8).replaceAll(" ", ""));
                if (nextID > maxId){
                    maxId = nextID;
                }
            }

            fileWriter.write("\r\n" + String.format(stringForm, maxId + 1, args[1], args[2], args[3]));
        }

        bRead.close();
        bufFileReader.close();
        fileWriter.close();
    }
}

вывод аналогичен предыдущему.
валидатор опять же не принимает. Строка новая в файл добавляется, а при проверке результат:
testtest
AlexSir
Как и в предыдущей версии, ошибка в переводе на следующую строку:
fileWriter.write("\r\n" +…
Alvisid
Тогда как выполнить условие 3? «При запуске программы с параметрами „-c productName price quantity“ в конец файла должна добавиться новая строка с товаром.»
Ryal
  • Ryal
  • 0
Постою, послушаю. Тоже такую тему завел вот тут: help.javarush.ru/questions/167410/%D0%BD%D0%B5-%D0%BF%D1%80%D0%BE%D1%85%D0%BE%D0%B4%D0%B8%D1%82-%D1%82%D0%B5%D1%81%D1%82-task-task18-task1827
Но у мне всегда ошибки в 3,4,5.
Alvisid
  • Alvisid
  • 0
  • Комментарий отредактирован 2017-02-10 16:41:37 пользователем Alvisid
Забавно, но в предыдущем более громоздком решении у меня был затык только на 5. А теперь и 3 с 4 добавились. Хотя вывод один и тот же. Жесть))))))
Appolinariy
прошу пардона, а почему например productNameLength = 38
если в задании productName — название товара, 30 chars (60 bytes)
?
тоже подошел к этой задаче
ShitovRE
это позиция последнего символа, отвечающего за наименование в строке. Т. е. он делает субстроку с позиции 8 до позиции 38:
priceLine.substring(idLength, productNameLength)
ShitovRE
Добрый день!
Создаю текстовый файл:
19846***Шорты пляжные синие***********159.00**12**

вместо звездочек пробелы исесьна. после чтения в строку или буфер последние пробелы из файла исчезают. Т.е. мало того, что их в строке нет, так они еще и из файла пропадают — это как понимать?
ShitovRE
Или это у меня уже глюки пошли… в идее дописываю — пропадают, В блокноте — все на месте…
Appolinariy
я args[0], args[args.length-1] и args[args.length-2] прямо из строки параметров забрал
а оставшийся кусок — наименование отпарсил острожненько с учетом пробелов внутри строки
ShitovRE
полдня убил из-за того, что к файлу приклеился Маркер последовательности байтов: 3 байта вначале…
Alvisid
  • Alvisid
  • 0
  • Комментарий отредактирован 2017-02-11 19:24:26 пользователем Alvisid
немного отрихтовал
/* 
Прайсы
*/

import java.io.*;

public class Solution {
    static String stringForm = "%-8.8s%-30.30s%-8.8s%-4.4s";

    public static void main(String[] args) throws Exception {
        switch (args[0]) {
            case ("-c"):
                createPrice(args);
                break;
        }
    }

    public static void createPrice(String[] args) throws IOException{
        BufferedReader bRead = new BufferedReader(new InputStreamReader(System.in));
        String fileName = bRead.readLine();
        BufferedReader bufFileReader = new BufferedReader(new FileReader(fileName));
        BufferedWriter fileWriter = new BufferedWriter(new FileWriter(fileName, true));

        if (!bufFileReader.ready()){
            fileWriter.write(String.format(stringForm, 1, args[1], args[2], args[3]));
        } else {

            int maxId = Integer.parseInt(bufFileReader.readLine().substring(0, 8).replaceAll(" ", ""));
            int nextID;

            while (bufFileReader.ready()){
                nextID = Integer.parseInt(bufFileReader.readLine().substring(0, 8).replaceAll(" ", ""));
                if (nextID > maxId){
                    maxId = nextID;
                }
            }

            fileWriter.write("\r\n" + String.format(stringForm, Integer.toString(maxId + 1), args[1], args[2], args[3]));
        }

        bRead.close();
        bufFileReader.close();
        fileWriter.close();
    }
}


Ещё интересный момент: если в переменной stringForm к первому параметру добавить точность(.8)
static String stringForm = "%-8.8d%-30.30s%-8s%-4s";


то валидатор выдаёт:

test

Что не закрыты потоки, хотя всё закрыто и изменений в коде в плане потоков не было, а при применении параметра точность к целому должно выбрасывать исключение. Так что я вообще ничего не понимаю
ShitovRE
  • ShitovRE
  • 0
  • Комментарий отредактирован 2017-02-11 22:56:13 пользователем ShitovRE
Ryal
  • Ryal
  • 0
  • Комментарий отредактирован 2017-02-13 12:12:02 пользователем Ryal
Прогнал bonus2 из этой темы — валидатор его не принимает.
Хотя решение тоже рабочее.

В общем — в #опу эту задачу.
Alvisid
С потоками разобрался: если вылетает исключение то потоки действительно не закрываются.
Alvisid
  • Alvisid
  • 0
  • Комментарий отредактирован 2017-02-12 12:21:26 пользователем Alvisid
Всем спасибо. Решено.
При дописывании в файл валидатор категорически против. Прошло только полное перезаписывание.
u909
От всей души спасибище тебе, добрый человек, за твой комментарий!
Задача решена с 50 попытки, проштудирован весь форум по этой задаче, порвано три бубна. Что только не перепробовано...

Уважаемые создатели курса. Условие задачи поставлено некорректно: "-c — добавляет товар с заданными параметрами в конец файла..." — это совсем не то же самое, что перезаписать весь файл + добавленная строка. Я, конечно, понимаю, что в реальности бизнес редко приносит путевую постановку задачи. НО! В реальных условиях есть возможность задать доп. вопросы по постановке, провести митинг(и), списаться по почте. При этом заказчик обычно заинтересован в конечном результате, потому охотно идет на сотрудничество. А не присылает письмо о 20 строках, а затем просто молча «не принимает» рабочий в соответствии с постановкой задачи код.
Ну, либо прошу выслать мне хрустальный шар для уточнения деталей задач. И еще бубны, новые бубны, мой личный запас иссяк.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.