#939 closed ожидаются исправления (задача сдана)
HW#3
Reported by: | Igor Engel | Owned by: | Egor Suvorov |
---|---|---|---|
Component: | HW #3 (Huffman) | Version: | 2.0 |
Keywords: | Cc: |
Description
Change History (3)
comment:1 Changed 4 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
Type: | ожидается проверка → ожидаются исправления |
Version: | → 2.0 |
comment:2 Changed 4 years ago by
Мда. С большинством согласен.
IoBinManip?.h/IoBinManip.hpp одновременно — жутковато.
Соколов предлагал так реализовывать заголовки с темплэйтами, чтобы было привычное разделение declaration/definition
В чём смысл писать argc <= i + 1 вместо i + 1 >= argc? Обычно, имхо, размер буфера справа и конструкция >= n очёнь стандартная.
Хм. Интересно. Чёт ни разу не видел >= n
Особенно setCode выглядит странно в совокупности с computeCodes() — так вершина сама считает или ей кто-то код рассказывает?
В зависимости от того, как строим дерево.
Возможно, стоило сделать что-то типа двух типов деревьев...
(from.fail() && !from.eof()) !from.bad() — тоже какая-то дико странная комбинация
Просто, если поток eof, то он fail... Поэтому "прочитать до eof'а" это какая-то нетривиальная операция, которую нельзя сделать если поставлен экспшен на fail... Так-что конкретно эта конструкция кажется единственный способ проверить, что мы адеватно дочитали до eof'а... А в остальных местах я уже запутался во флагах и исключениях из-за этой фигни с eof'ом... Мда.
comment:3 Changed 4 years ago by
Про заголовки: окей, понял. Но я бы тогда убрал #pragma once
из IoBinManip.hpp
(его вообще должен включать только IoBinManip.h
). И там тогда нельзя делать никаких typedef
, потому что это уже не деталь реализации, а публичный интерфейс.
Если в зависимости от того, как строим дерево — это либо два вида деревьев, либо один общий (скорее всего, с setCode
), и одна функция "задай коды на этом дереве так-то".
P.S. А ещё код непортируемый: нужно открывать файлы в бинарном режиме.
Увы, третьей попытки на баллы нет. Захотите дорешать просто так — переоткрывайте тикет.
Корректность 7.5/9
raw
/compressed
, а должна выводить разное в зависимости от ключей.Тесты 2.5/8
TestBitWriter
testBitWriter
возникает ощущение, чтоHuffman.cpp
не протестировано. Подозреваю, следствие архитектуры (смотри ниже).testPrefixFreenesOn
, но вы просто переложили поиск багов с кода на тесты. Это нельзя проверить глазами. Должны быть простые тесты, которые можно проверить глазами, не запуская код.readMetadataAndBuildExtractor
writeMetadata
Архитектура 1/5 — основная претензия к разделению на файлы и
HuffmanArchiver.cpp
CLI
— используйте конструктор вместоparseArguments
HuffmanNode
. Да иHuffmanTree
тоже.readMetadataAndBuildExtractor
намекает, что у насHuffmanTree
может внутри себя строить некийExtractor
, который что-то делает. И, видимо, его прям надо построить в каких-то случаях?descend(HuffmanNode, bool)
— похоже на метод Node.HuffmanNode
убрать. Это очень усложняет код. Это, на самом деле следствие предыдущего пункта: если куча ответственности, то у каждого объекта куча промежуточных состояний, методов и сложных инвариантов не по делу.setData
не нужно,setLeft
/setRight
/setCode
тоже...setCode
выглядит странно в совокупности сcomputeCodes()
— так вершина сама считает или ей кто-то код рассказывает?getLeft
/getRight
incWeight()
— на единицу? Для подсчёта статистики? Это единственный способ протестировать дерево? Брр.IoBinManip.h
/IoBinManip.hpp
одновременно — жутковато.HuffmanArchiver
зачем-то руками разбирает битовый поток. ХотяBitWriter
у вас был.ceildiv
— это очень тревожный симптом: вместо того, чтобы в одном классе сосредоточить ответственность записи/чтения и корректного подсчёта символов, вы считаете это по отдельности руками. Вот, пришлось даже специальную функцию завести. И следить, что она везде корректно используется.Стиль 4/8
noexcept
у методов.if
и(
=
вbool create = false
.argc <= i + 1
вместоi + 1 >= argc
? Обычно, имхо, размер буфера справа и конструкция>= n
очёнь стандартная.CLIException
— используйтеusing runtime_error::runtime_error
std::string x = "";
— строчка и так всегда пустая по умолчанию.if (!inp.good())
— простоif (!inp)
(from.fail() && !from.eof()) || !from.bad()
— тоже какая-то дико странная комбинацияArchiveSizes
— вHuffman.h
, а не вHuffmanArchiver.h
.Huffman.cpp:169
: нет, raw pointer там вполне адекватен: мы хотим мутабельный невладеющий указатель на что-то. Ровно правильное место для чистого указателя.HuffmanArchiver.cpp:8
: да, надо.HuffmanArchiver.cpp:54
: нормально. Тут просто честный классический итеративный алгоритм. Хаффман принципиально по-другому не написать. Любая попытка завернуть его в подобие fold обречена на провал. Он придуман так, чтобы было удобно писать в итеративном стиле. В состояние дерева точно "текущую вершину" пихать не надо, дерево существует независимо от алгоритма (де)кодирования.testArchive
: принимайте поconst&