Pull to refresh

Comments 79

UFO just landed and posted this here
Не могу не спросить — вам шашечки или ехать?

Мне кажется, этот комментарий на 100% можно развернуть в обратную сторону.
Раньше код "ехал" — выполнял что должен выполнять в 99.9999999% случаев и если где-то проскакивало 1000КБ — то было это при выводе на экран и в общем никого не колыхало (ничего не могло сломать).
Теперь это не только "ехать", но ещё и "шашечки", которые, как-бы, и не очень-то были нужны (для "ехать").

Более того, всегда можно вернуться к циклу.

UFO just landed and posted this here

А если Вы биолог? Или некромант с наномашинами/испытатель экзоскелета...

Если знакомест было 3, а получили 4, то это могло ввести заблуждение 100 вместо 1000, например

Там же в строку потом единица измерения приписывается. Скорее потеряется буква "б", чем нолик из середины строки.

Скорее уж, "1000." вместо "1000.0". Впрочем, учитывая, что возвращается строка вместе с единицей измерения, выше риск, что затрётся последняя буква. Или, что хуже, потеряется нулевой символ при использовании буфера фиксированного размера.

Это ж Java, о каком нулевом символе речь?

Красивый бажный код подобен помоищному бажному коду, только с красотой.


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

UFO just landed and posted this here

Кстати, сам рассматриваемый в статье ответ на SO теперь тоже исправлен — и там вообще другая версия предложена, более грациозная:


public static String humanReadableByteCountSI(long bytes) {
    return bytes < 1000L ? bytes + " B"
            : bytes < 999_950L ? String.format("%.1f kB", bytes / 1e3)
            : (bytes /= 1000) < 999_950L ? String.format("%.1f MB", bytes / 1e3)
            : (bytes /= 1000) < 999_950L ? String.format("%.1f GB", bytes / 1e3)
            : (bytes /= 1000) < 999_950L ? String.format("%.1f TB", bytes / 1e3)
            : (bytes /= 1000) < 999_950L ? String.format("%.1f PB", bytes / 1e3)
            : String.format("%.1f EB", bytes / 1e6);
}

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

Самое смешное что с маттерн мачингом это выглядело бы куда более понятно, да еще и эффективно.

Главное чтобы long "вдруг" в 2 раза длиннее не стал :)

А я искренне не понимаю чем цикл не устроил, там хоть и магнитуды автор рандомные указал, но исправить очень легко и работало бы без багов.
Оригинальный вариант с логарифмом ужасен, не настолько как в финале, но все же.
Предлагаю на собеседованиях если человек четко может дать определение логарифма — отсеивать, пусть математики вселенную изучают, а не код пишут.
Предлагаю на собеседованиях если человек четко может дать определение логарифма — отсеивать, пусть математики вселенную изучают, а не код пишут.
А в биологи не брать тех, что знает число пи хотя бы до одного знака до запятой?
Неожиданное открытие биологов:
«В незапамятные времена участвовал в конкурсах работ МАН. Сам по математике, но однажды оказался зрителем на докладе в секции биологии. Работа была посвящена изумительному наблюдению, подкрепленному большим числом замеров: окружность любого муравейника примерно втрое длиннее его диаметра.»
С иронией: замеряли-то небось в мирное время? :)

Вы про повреждения от попаданий снарядов и бомб?


Кстати, подобное исследование было бы действительно интересным — по какой именно математической формуле муравьи восстанавливают повреждённые муравейники — снова приводят их к круглому конусу, или же получается некая сглаженная пирамида с основанием в виде невыпуклого многоугольника?)

Я думаю, имеется в виду бородатый анекдот:


В военное время число Пи может достигать четырёх.
Я помню этот анекдот, но вопрос поведения муравьёв после разрушения муравейника для меня более интересен оказался)

Справедливости ради, МАН — это школьная "академия". Для школьников такое "открытие" вполне простительно.

Да, тут сложно не согласиться.
На мой взгляд, достаточно было бы просто 10^n заменить на 2^n.
Оригинальный вариант кода, пусть и неправильный, был красив. А после всех перипетий получилось помóище

Добро пожаловать в разработку библиотечного кода! Пишешь красивую реализацию чего-то, приходит 100500 человек, которые показывают тебе, что на вышедшем 100 лет назад железе, на Северном Полюсе, когда Луна в Водолее твой код не работает. И требуют исправлений. И ты исправляешь, потому что это же библиотека, должна работать везде.
И что обидно, чаще такое оформляется не пулл реквестом, а исуей.
Так, что ребята аккуратнее с публикацией опенсорса. Люди по дефолту
считают, что Вы теперь обязаны пожизненно сопровождать свой код бесплатно.

А как вы считаете, правильнее публиковать исправление очевидной и воспроизводимой (для тебя, на твоём железе) проблемы пулл-реквестом, или же иссуей + пулл-реквестом, фиксящим эту иссую и ссылающимся на эту иссую?


Я вот не так уж давно опубликовал 3 таких вот иссуи с фиксами в одну промышленную (!) библиотеку, но до сих пор ни один из пулл-реквестов не принят, а откомментирован разработчиками лишь одна из трёх иссуй, и ни один из реквестов.

Я в этой статье увидел подтверждение своему отношения к коду с оверфлоу.
Вам дан только пример для идеального случая, который показывает суть как надо решать
задачу. И то, что его всегда надо допиливать тем, что автор вынес за скобки
для простоты понимания сути.

Не надо его в лоб копировать в свои проекты.
А я в этой статье увидел подтверждение своему отношения к коду с оверфлоу.
Я бы сам написал код не лучше, чем первый вариант ответа, то есть тоже с багом. И уж точно хуже, чем текущий вариант, без ошибки. По сути использование кода со SO ничем не отличается использованием сторонних библиотек. Да, там могут быть ошибки, ну так они везде могут быть, даже в самом процессоре.
UFO just landed and posted this here

Осталось самая малость — правильный юнит-тест.
Со всеми кейсами типа 999 950 -> 1МБ и прочих 999 949 999 999 999 999.

Не забудьте только взять unit-тест тоже со StackOverflow. Тогда точно-точно все будет работать. Всегда. Без вопросов. :)
UFO just landed and posted this here

Ирония? Нет, не слышали.

UFO just landed and posted this here
я думал самый простой и эффективный способ это битовый сдвиг

    public static void main(String[] args) {
        int byteSize = 123456789;
        int mByteSize = byteSize >> 20;
        System.out.println(mByteSize); // 117МБ
    }

Код не о делении на 2^20, а об определении той единицы измерения, при которой число станет удобно читаемым.

Однако так и считаем, тянем с собой последние значащие цифры и по последней определяем ""куда ближе", тут проблема скорее в варианте с десятичным представлением (кило с т.з. СИ), на java решить можно только преобразованием в цикле...

UFO just landed and posted this here
Да, получилось реально помоище. Куча неявной математики и странных magic number'ов.
Лучше бы кучу IF'ов написал.

В исходном исправленном комментарии SO именно куча троичных операторов устроена.

Я видел, не слепой. И читаемость у них хуже, чем у IF'ов.
В данном конкретном случае не хуже, а наоборот. Если раскорячить этот код в три раза, более понятным он не станет.
Так-то можно было перевести всё к интервалу 1-unit, а к логарифму поправочку прибавить (возможно, отрицательную — лень думать, простите) — получилось бы гораздо элегантнее, IMHO
Вариант c циклом четкий, красивый, обозримый.
Его корректность легко доказать.
Я бы еще оттуда убрал вещественную арифметику, оставив только целые числа.
И убрал выход за пределы массива при нуле байт :)
StackOverflow уже больше десяти лет в обед, могли бы и пораньше сделать выводы о том, что «В ответах на Stack Overflow могут быть ошибки, даже если у них тысячи плюсиков.».
… а в соседней теме пишут, что не только называть говнокод говнокодом, но и просто критиковать чужой код — является «токсичностью», противоречащей корпоративным нормам.

"Токсичность" — имхо, само определение этого слова противоречит изначальной сути Интернета. И очень многое в Интернете делается под эгидой борьбы с этой "токсичностью".
Пчёлы против мёда.

:-O
Тут же всего лишь шесть шагов, зачем логарифмы считать?! Когда можно просто IF'ами сделать.
А если ещё и с середины сравнивать, то результат вообще за пару сравнений найти.
В самом популярном фрагменте кода за всю историю StackOverflow ошибка! 

С удивлением узнал о таком коде. По тегу java вы легко найдёте гораздо более популярные вопросы и ответы. Похоже, автор имел в виду только свой популярный код.
Популярность мерялась не плюсиками на SO, а появлениями этого фрагмента кода в коде проектов на Github.
Т.е. автор статьи ни разу ни чем не померил, а утверждает, что это самый популярный фрагмент? Я выше писал, что в вопросах по Java гораздо больше плюсов, а это уже признак того, что код и в проектах на GitHub встретится чаще. Грубо говоря, исправление ошибок в memory allocate на языке C, сортировка и т.п. встретится в десятки раз чаще, чем некий мало кому нужный код по форматированию Мб.

В обсуждаемой заметке в разделе "Исследование по атрибуции" всё сказано — он увидел свой код на первом месте в исследовании, где был взят некий критерий популярности. Ссылки и картинка наличествуют.

Т.е. автор статьи ни разу ни чем не померил, а утверждает, что это самый популярный фрагмент?

Тенденция «Я Пастернака не читал, но осуждаю», набирает обороты на хабре. Ведь буквально первое же предложение в статье содержит ссылку на исследование, где и пришли к выводу о популярности данного фрагмента кода.
Вы можете говорить только за себя. Данный текст я читал и не заметил там указания, что данный фрагмент кода является самым популярным на GitHub. Я уверен, что это совершенно не так, скорее, это один из самых редких и мало кому нужных фрагментов кода из GitHub.
Данный текст я читал

Прямо-таки купили за 35 евро? Я вот не покупал, всего лишь зашел в References исследования и увидел там ссылку на данный ответ на Stackoverflow. Единственный ответ с кодом со Stackoverflow во всех References, что как бы намекает, ведь исследование называется «Usage and attribution of Stack Overflow code snippets in GitHub projects».

не заметил там указания, что данный фрагмент кода является самым популярным на GitHub

Во-первых, вы все путаете. Все ещё. Не «самый популярный на Github», а «самый копируемый сниппет со Stackoverflow, встречающийся на Github». То есть у данного вопроса самая большая область пересечения этих двух плоскостей: «код с ответа на SO» и «фрагмент кода на Github». Он популярен в своем первозданном виде. На Stackoverflow есть множество популярных ответов, с которых не́чего копировать, потому что они, внезапно, не оформлены, как ready-to-use сниппеты.
Но для вас этот факт как будто личное оскорбление.
Давайте рассуждать логически. Работа с файлами в репозиториях и вообще в среднем занимает примерно 1% кода, я думаю, даже меньше. При этом подсчёт размера файла нужен ещё примерно в 1% случаев от работы с файлами. Итого данный код нужен в исчезающе малом количестве случаев. Я вообще не припомню, чтобы он когда-то кем-то был использован или вообще упомянут. Этот код — пустышка, он фактически почти никому не нужен. Я убеждён, что это один из самых редких кусков кода, который вы только можете увидеть на GitHub. Никакого толкового исследования автор не мог провести, потому что у него нет таких инструментов. Он не может быть уверен, что код на GitHub взят с SO, а не наоборот, что этот код взят именно в таком виде, а не переделан. Фактически вся статья — полная профанация.
На Stackoverflow есть множество популярных ответов, с которых не́чего копировать, потому что они, внезапно, не оформлены, как ready-to-use сниппеты.

Это проблема тех, кто копирует код. Захотят — скопируют, захотят — напишут сами. Не вижу проблемы в том, что код не отформатирован.
Удивлен что этот код нейросеть не прикрутили =)
Индивидуально конечно, но лично мне и первый вариант не кажется красивым и хорошим. Нагромождение конструкций, в котором сходу не поймёшь, как он себя ведёт в предельных случаях. Я бы предпочёл что-то вроде такого:

public static function humanReadableByteCount($bytes)
{
    if ($bytes < 1024) {
        return $bytes .' b';
    }

    if (($bytes /= 1024) < 1024) {
        return round($bytes, 2) . ' KB';
    }

    if (($bytes /= 1024) < 1024) {
        return round($bytes, 2) . ' MB';
    }

    if (($bytes /= 1024) < 1024) {
        return round($bytes, 2) . ' GB';
    }

    return round($bytes/1024, 2) . ' TB';
}


(просто иллюстрация, не обязательно соответствует всем стандартам)
<sarcasm>У вас код не соответствует идеологии структурного программирования!</sarcasm>
В KB, MB, GB множитель 1000 а не 1024. Во всяком случае у НИХ. Хотя у нас на информатике детей по старинке учат, что в килобите 1024 бита :-(
UFO just landed and posted this here
Где я взял предубеждение что нужно соблюдать стандарт? Вы же сами пишете, что пробовали ввести стандарт и тут же называете стандарт предубеждением!
Читаем Хабр habr.com/ru/post/193256
Или на стандарт IEEE 1541/IEC 60027-2 можно не смотреть?
UFO just landed and posted this here

В предложенном мной варианте замена KB на KiB тривиальна.
Как и вынесение делителя в переменную типа $divisor = isSi? 1000: 1024;

Во всех операционных системах, во всём популярном софте в KB, MB, GB — множитель 1024 и никак иначе. Множитель 1000 стал использоваться там, где нет жёсткой привязки к степеням двойки. Ну и из соображений маркетинга.


Да, опытные люди знают про существование приставок Ki, Mi, Gi, но вот в обиходе они практически не используются. Люди привыкли, что в отношении количества информации эти приставки обозначают множитель 1024.


Кстати, вас не смущает использование фунтов, миль, баррелей? Эти единицы имеют разный размер в зависимости от контекста.


Чтобы исправить ситуацию, нужно, чтобы

Эти килобайты по основанию 1000 пришли от производителей дисков (до этого гениального решения продавать 1000000 байт вместо 1024*1024 и началась эта история, до того(по крайней мере из того что я видео) никто ни о каких 1000^n и не задумывался…
p.s. это как транСакции в финансах, когда гуманитарии добрались до ....

Этот код еще не будет работать, если электричество отключили.

Напомнило о баге, который я репортил в Гитлаб, когда на коммит, сделанный 14 декабря, 15 марта пишется "2 months ago". Тоже небось со StackOverflow взяли пример, где автор не учел несколько пограничных случаев…

Это классика, буквально недавно встретил серьёзный такой расчёт (финансовый) в котором количество месячных периодов считали делением на 30.5, ну ладно те кто в Экселе делал, они не it-ники, но это спокойно пролезли через весьма недешовых специалистов при переносе в пром...

А не могли бы вы уточнить, как из утверждения об асимптотике сложности делается вывод о скорости в данном конкретном случае? Особенно, если вариант с логарифмом имеет сложность О(1)?
А разве логарифм вычисляется за О(1)?

Если под N понимать не разрядность числа, а количество возможных единиц измерения — то да.

Что выполняется быстрее показывают бенчмарки в конкретном окружении на конкретных данных, а не ассимптотика.

А у меня вот такое получилось, правда на Python (ибо Java я варить не умею), но думаю в Java тоже есть "целочисленное деление" .


def humanReadableByteCount(size: int, si : bool) -> str:
    unit = 1000 if si else 1024
    exp = int(math.log(size)//math.log(unit))
    pre = "{}{}".format(("", *("kMGTPE" if si else "KMGTPE"))[exp], ("" if si else "i"))
    return "{:.1f} {}B".format(size//(unit**exp/10)/10, pre)

Т.е. вместо деления сразу на 1000, сначала делим на 100, отбрасываем дробную часть, а потом делим ещё на 10. Таким образом при форматировании до 1 знака после запятой нет никаких округлений дробной части в большую сторону.

Sign up to leave a comment.

Articles