Opened 3 years ago
Closed 3 years ago
#687 closed ожидаются исправления (задача сдана)
HW_3 kirill.kondratyuk
Reported by: | kondratyuk.kirill | Owned by: | Дмитрий Лапшин (lapshin) |
---|---|---|---|
Component: | HW #3 (Huffman) | Version: | 3.0 |
Keywords: | Cc: |
Description
Здравствуйте
Я пока что не сделал исключения и тесты, но код работает и валгринд не особо ругается:)
С уважением, Кирилл
Change History (9)
comment:1 Changed 3 years ago by
Component: | HW #2 (X0) → HW #3 (Huffman) |
---|
comment:2 Changed 3 years ago by
Owner: | changed from Дмитрий Лапшин (lapshin) to kondratyuk.kirill |
---|---|
Type: | ожидается проверка → ожидаются исправления |
comment:3 Changed 3 years ago by
Owner: | changed from kondratyuk.kirill to Дмитрий Лапшин (lapshin) |
---|---|
Type: | ожидаются исправления → ожидается проверка |
Version: | 1.0 → 2.0 |
Пока что на исключения меня не хватило
write_thing - читает что-то и прибавляет к счетчику память которую метод записал, поэтому счетчик я думаю что нужен
а вот что с текстовыми методами ввода вывода я не понял. нам же в задании написано мол сожмите текст.
про массив 256 знал, но если у нас будет только один символ, то мое решение будет лучше, а так как зачастую разлчиных символов в тексте примерно 50, то реально я разницы не вижу.
создал класс интерфейс просто чтобы избавиться от копипасты немножко, то есть там овер дофиг переменных у меня, для которых можно было бы не создавать отдельную структуру, а впихнуть все в этот класс и норм.
умные указатели еще не встроил, но скоро.
Ну и написал тестов еще
comment:4 Changed 3 years ago by
Еще не понял про новые стандарты, то есть можно было бы написать лямбду - да, но честно говоря мне кажется что функтор здесь выглядит посолиднее.
про число->строка->бит сначала реальо показалось выгодным:)) но не сейчас:|
еще те методы которые read_text_count_entries разделил все-таки и вынес в unnamed namespace
для всех функций написал тесты, по-моему, кроме тех что непосредственно все собирают вместе
Когда напишу исключения помню что их можно тестить - затещу
Завтра скорее всего будет.
comment:5 Changed 3 years ago by
В общем и целом сделал:
- Написал лямбду вместо функтора. Но остался вопрос, как это впихнуть в одну строчку, дабы не пложить новых переменных.
- Магические числа вынесены в переменные внутри cpp файла. Кроме чисел 0 и 1 при работе с битами.
- Больше не гоняю строку в бит и тп.
- Теперь использую комбину seekg, tellg
- Вот этого я на самом деле не понял. Но переделал так, что теперь эти потоки ввода и вывода в приватных полях класса
- Переименовал
_thing
в_to_file
. Там параметр не длины, а счетчик памяти, который, по моей задумке, нужно менять при записи. Можно было бы его менять вне функции, но я где-то мог его забыть, а так компилятор сам напишет мне мол забыл что-то передать в функцию.
- Теперь пользуюсь только
read
иwrite
. Поэтому теперь открываю все файлы как бинарные, так как все равно читаю либо по чару(биту), либо что-то специфичное, но зная что читаю
- Сделал вместо мапы массив на 256. Тут заюзал
accumulate
с последней практики
- Пока что умней
- Тут я оч хотел избавиться от копипасты таким образом, поэтому так и сделал.
- Учел и смог
Тесты сделал.
Программа не падает и работает как часы:)
comment:6 Changed 3 years ago by
Owner: | changed from Дмитрий Лапшин (lapshin) to kondratyuk.kirill |
---|---|
Type: | ожидается проверка → ожидаются исправления |
Переводов строчки в конце многих выводов тебе яявно не хватает.
Корректность:
- Cтатистику выводишь неверную. Что-то не так, может просто порядок чисел на разжатии. А может и не только, простым фиксом не поправилось. Пересмотри как в условии.
- Иногда падает. Хз с чего, просто брык.
- Иногда разжимает другой файл.
Ну хотя бы иногда работает, это да) 8.
Тесты:
- Имя. Программы.
- А компаратор векторов чем не подошёл?
- Зачем в тестах выделяется дерево на куче?
- Ну и недописанные тесты ж. Явно ещё крайних случаев не хватает.
3.
Стиль:
- Входные байтики лучше считать
unsigned
, а то вдруг захочется обратиться как по индексу. Интересно к чему это я. return in.eof();
Сколько раз говорить как проверять успешность ввода-вывода?- Да и вообще комбинация исключения + кода возврата для сообщения ошибок это странно. Тем более когда ты как бы размер уже знаешь.
std::string
от чариков оооой. А если там ноль?)))))- Меня очень смущает класс
node
: сырые указатели (ты все спец операции сделал правильно? программа-то падает почему-то...),std::string
для чего-то, всё очень публичное и в заголовке, куча конструкторов, а в cpp зачем-то дублируется оборачивающими функциями, короче не очень верю ;) - Кажется не всё из заголовка достойно там быть.
- Я же правильно понимаю, что твой ожидает, что код в Хаффмане всегда до 8 бит?
- Всякие
addition_size
и прочее просится в поля класса, а функции записи в методы, чтобы было удобно. - Порядок функций в файле очень странный)
Короче стало лучше, но ощущение непродуманности всё ещё гуляет, причём напрямую намекая на ошибки местами. 5.
comment:7 Changed 3 years ago by
Owner: | changed from kondratyuk.kirill to Дмитрий Лапшин (lapshin) |
---|---|
Summary: | HW_2 kirill.kondratyuk → HW_3 kirill.kondratyuk |
Type: | ожидаются исправления → ожидается проверка |
Version: | 2.0 → 3.0 |
Стиль
- Действительно интересно, потому что переменных кроме
unsigned
у меня просто нет.
2.3. Эти пункты в связке. Ну вообще я хотел хоть как-то отловить модификацию сжатого файла с информацией, мол если он передан не в том формате, то все очень плохо. Но пускай будет UB.
4.5. Изменил на аналог. Теперь это std::vector<uint8_t>
. Написал свою функцию поиска без лямбд так как так короче.
- Вот тут не понял совсем. В заголовке у меня только функции вида
save
,proceed
и конструкторы, причем только их объявления. Да у меня есть шаблонные функции для считывания различного рода переменных, но если я вынесу их в cpp, то будет больше копипасты. - Нет, неправильно понимаете. Мой код каждому элементу сопоставляет какое-то установленное алгоритмом количество битиков. Далее все это конкатенирует и бьет на блоки по байту, то есть по 8 битиков, так как вставлять 1 бит мы не умеем вроде как.
- Они и так поля класса, если я правильно понял о чем вы. Могу их только внутри еще в класс запихнуть. Я бы мог передавать метод который нужно дергать для увеличения счетчиков, но почему бы не сделать так? Так ведь будет намного меньше кода и как по мне так красивее, да я передаю управление над ней в какую-то неведомую функцию, но если я ее передаю, то я точно знаю в какой момент и куда я это делаю.
- Порядок могу поменять на более подходящий согласно моему предпочтению. Где-то читал, что нужно соблюдать уровни абстракции.
Тесты.
- Имя. Программы. Я не понимаю, что вы имеете в виду. Объединил все в один блок.
- Компаратор векторов я не нашел, поэтому написал свой. Теперь узнал, что есть стандартный.
- В тестах выделяется дерево на куче для того чтобы эмулировать работу реального алгоритма, поэтому эти тесты наиболее приближены к реальности.
- Не смог понять какие еще тесты нужны, я нашел что при каких-то рофельных символах в тексте у меня он откидывается видимо. Если нет, то я не знаю что не так. Поэтому протещу это еще.
Корректность.
- Не понимаю что за неверная стата. Помогите, дайте тест какой-нибудь этакий.
- У меня вот не падает ни на чем кроме картинки. Теперь не падает вроде.
- Что это значит.
Не закрывайте, пожалуйста, сразу этот тикет. Я хочу понять как должно быть.
comment:8 Changed 3 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
Корректность: со статистикой как раз трудно подсказать, у меня любой пример отичается. Но теперь оно не ломается и поэтому ок, 14.
В тестах выделяется дерево на куче для того чтобы эмулировать работу реального алгоритма, поэтому эти тесты наиболее приближены к реальности.
Если хочется интеграционных тестов (хорошее желание!) это делается не так и, честно, мало относится к приближению к реальности.
Например, стоило бы потестировать, что происходит если некоторый набор байт сжать и разжать: если на выходе другой ответ, это явно намекает, что при использовании кода в реальности он не сработал. А если сработал это хороший знак.
По сути ты тестируешь лишь построение дерева. Это хорошо, конечно, но можно больше. 4.
Стиль:
Про чтения: мне казалось у тебя где-то было чтение в char
, а он пёс знает какой знаковости. Кажется даже стреляло именно на тестах с бинарными/юникодными файлами, где есть символ с старшим битом, читается как отрицательный, обращаешься в массив, ОЙ, дальше UB. На деле разжимаешь не то или падаешь. Может не явно, а как раз из std::string
или чего-то такого. Сейчас не виду char
и не вижу проблем (ну кроме статистики, не знаю что с ней не так).
Дальше про стиль: в заголовке выставлен read_from_file
, который там не сильно нужен (этот шаблон нужен лишь в реализации), и более того: вместо того чтобы в него передавать счётчик, можно было бы:
- Сделать это шаблонным методом класса-состояния (и не передавать этот счётчик и файл постоянно).
- Можно было бы просто выделить класс для бинарного ввода-вывода, если не хочется замешивать всё это в класс про само сжатие. (тем более для битового у тебя уже есть!)
- А ещё можно было бы просто делать tell/seek)
Во всех этих подходах функция ближе к месту использования, имеет более чистый интерфейс, ну и таскать кучи параметров (и чтобы в них не налажать) намекают, что есть другое решение.
Надеюсь так моя претензия стала понятнее.
Сюда же идёт struct node
:
- А зачем она в заголовке?
- А зачем если она в заголовке у неё всё публичное, хотя внутри явно два владеющих сырых указателя?
- Если нет умных указателей, где правило пяти?
Представь что ты используешь сжиматор, который написал я, но видишь твой заголовочный файл. Очень много вещей, которые пользователю не нужны. Ну так и спрячем их: и чтобы не он заиспользовал лишнего (и неправильно!), и чтобы себе свободу оставить.
В твоём стиле, например, заголовок мог бы не содержать определение node (для взятия указателя оно не нужно), или класс был бы приватный в worker, или имел бы полные спецметоды.
Вообще понятно, что в рамках реализации нормально сделать какую-то внутреннюю структуру публичной по полям, раз её снаружи всё равно не достать.
Ещё есть константы которые не очень связаны между собой в коде, когда связаны по смыслу и выражаются друг через друга (256 и 8). Есть деструктор который делает close на файл (хотя он и сам закроется) и удаляет дерево (хотя мог бы держать корень дерева явно/через unique_ptr).
Эти пункты сильно портят впечатление от кода: много оставлено мест, через которые могут вещи ломаться, хотя прикрыть их несложно. 7.
Тикет не закрываю, если ещё что-то есть обсудить.
comment:9 Changed 3 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
Пааапка и исполняемые фаааайлы
Корректность: я увидел необработанное исключение на каждом тесте. Вообще на каждом. Я даже руками запустил и тоже упало с
Собственно работать оно не может, потому что ты выставляешь флаг исключений на чтение а дальше читаешь циклом while. Цикл while не умеет ловить.
А в чём вообще план включать исключения и не ловить?
Если подоткнуть чтобы хоть как-то жило то: сообщает неправильную статистику (видимо на расжатии). Пустой файл крайне удивляет программу.
Тесты: нема.
Стиль:
std::string compressed_text;
ты сжатый текст и в памяти держишь?! Не надо пжлст)write_thing
содержательные имена) Можно было бы сделать методами класса, чтобы не выставлять уж странный параметр про длину. Кстати нужен ли он?..u_int32_t
это кто такой?) Кстати, число вхождений байт (256 чисел) можно было и массивом/вектором.delete
не писать потом и правило пяти не вспоминать?update_codes
для пользователя?strcmp
: смотри как я умею4.