Транзитивность и «Ведьмак»
Цитата из книги «Мозг рассказывает. Что делает нас людьми» Вилейанура Рамачандрана:
«Обезьяна А видит, как обезьяна В запугивает и подчиняет себе обезьяну С, которая в некоторых ситуациях успешно подчиняла себе А. Не будет ли А убегать от В, применяя транзитивность? (В качестве контрольного эксперимента нужно будет показать, что А не убегает от В, если В подчиняет
какую-нибудь случайную обезьяну С.)»
Вот это отсутствие понимания транзитивности силы — то, что меня вымораживает в мире «Ведьмака».
Я плохо знаю книжную серию (собственно, всё что я читал — два рассказа в составе сборника начала
Этим, конечно, не только «Ведьмак» страдает, но там это происходит из раза в раза,
Успеть пристегнуться
Очень неприятно, что многие таксисты сразу трогаются, когда садишься в такси. Куда ни шло, если сажусь один, — довольно быстро пристёгиваюсь, а если мы садимся с дочкой, пристегнуть нас двоих быстро не получается.
Приучился в таких случаях не закрывать за собой дверь, пока мы с дочкой не будем готовы ехать. Если интересуются, спокойно объясняю ситуацию, этого хватает, — просят закрыть, говорят, что подождут.
До того как я это придумал, пробовал просить не ехать, пока не пристегнёмся, но это почти никогда не работает.
Эффект неудавшейся прокрутки
Есть
Будто срабатывают противоположные мышцы — одни стараются сдвинуть глаза по предполагаемому движению страницы, другие, видимо подключенные
Интересно, это у всех так?
«Гопник-2»: контрибьюторы
Фантастика! У меня на проекте буквально за эти выходные появилось ещё два контрибьютора.
deadem перевёл проект на сборку cmake, принёс библиотеку форматирования fmt и приделал к нему CI «Гитхаба», теперь сборка идёт прямо там. kartaris убрал fmt в зависимости, принёс менеджер пакетов conan и дописал код для использования в нём fmt.
Это для меня новый интересный опыт — у меня не было возможности поработать на «Гитхабе» с контрибьюторами, да и само по себе приятно, что к проекту подключились новые люди и затащили в него достаточно сложные штуки.
Пин-коды в СМС
Очень нравится как шлёт
Проекты дочки
У дочки последний примерно год или два очень интересный период — одним за другим делает так называемые «проекты», иногда по нескольку в день.
С одной стороны я очень радуюсь взрыву этого креатива, с другой стороны это просто некуда девать — никакой квартиры не хватит. Что делать с этими поделками не вполне ясно, выбрасывать жалко, хранить негде.
Долго думали что с ними делать, пока думали, скопилось столько, что выбрасывать
Для понимания масштаба, вот что было сделано за последние два дня, из того, что я успел заснять. Вчера они с бабушкой сшили ещё несколько подушечек (мышку, ому из «Навсикаи из Долины ветров» и ещё
Пора аккумулятор менять на «Макбуке»
Блин, засада, система пишет, что аккумулятору на «Макбуке» рекомендуется обслуживание. Не скажу, что ничего не предвещало —
Ньюборн-фотограф
Уж не знаю почему, но английский легко даёт новые значения старым словам или выдумывает новые, а современный русский стесняется так делать. Наверное просто дело привычки, большинство россиян консервативно и боится всего нового.
Как бы то ни было, русский язык, в основном, пользуется заимствованиями. Не вижу в этом ничего плохого, но только если в этом действительно есть смысл. Если понятия нет в русском, а из собственной элементарной базы мы его создавать стесняемся, то
Новые смыслы — это хорошо, прекрасно, когда язык обрастает понятиями, а не теряет их (как в случае замены «из» на «с»). Но только если они новые. Зачем тащить в язык чужие слова, если у нас есть свои такие же?
Поэтому мне не нравятся «заимпрувить» («улучшить») или «заюзать» («использовать»), но я ничего не имею против ещё пока свежего «кринжа» или более уже старого «чирлидера». Я готов смириться даже со словом «читабельный», у которого есть русский брат «читаемый», потому что у «читабельного» как будто бы есть более узкий смысл.
Но недавно во мне неслабо так бумкнуло, когда в чате нашего ЖК разместили рекламу
Си++: форматированный вывод (продолжение)
Очень раздражает, что вместо того, чтобы писать прикладной код, я вынужден бороться с компиляторами, да не с одним, а с тремя, под разные операционные системы. Я как будто пытаюсь писать не на одном языке, а сразу на трёх, похожих, но не полностью.
Мои приключения c форматированным выводом в Си++ до сих пор не закончились, оказалось, что последний вариант обёртки над std::snprintf в одном из компиляторов не собирается с одним из видов аргументов, пришлось его обернуть в std::cref.
Умные люди в комментариях советуют перейти на внешнюю библиотеку fmt и я уже сделал подход к снаряду, но под mingw у меня сборка пока не заработала. Завтра попытаюсь ещё раз — хочу подключить библиотеку подмодулем к своему репозиторию встроить компиляцию в процесс сборки своего проекта. Мне кажется, что я делаю всё правильно, а вот mingw так не кажется, попытаюсь завтра побороть.
Двухфакторная аутентификация
Сейчас повсеместно внедряется двухфакторная авторизация, чтобы снизить риски взлома аккаунтов злоумышленниками. Это правильный шаг, конечно, хоть и неудобный.
Я тут недавно перебирал ящики с вещами и приливная волна барахла вынесла на свет карточки второго фактора авторизации, которые лет десять назад выдавал банк «Ак Барс».
Для чего они точно использовались, я не помню, кажется их запрашивало приложение на входе, но может быть они были нужны для обращения по телефону или через кассу.
Когда они кончались, в банке можно было получить следующий комплект, предъявив для этого специальный код. Позже новый комплект стало возможным получить в банкомате на бумажной ленте.
Си++: форматированный вывод
Си++, похоже, язык для воспитания героев — создаём трудности на ровном месте и начинаем их преодолевать. В моём случае началось всё с разумной, как мне до сих пор кажется, идеи — заменить сишные безобразные строки char * на прекрасный класс std::string из Си++.
В процессе в комментариях мне написали, что вместо него надо использовать std::string_view, чтобы избежать копирования. Так я узнал, что за строки в Си++ отвечают не один класс, а четыре — есть ещё базовые классы, с приставкой base.
Заодно пришлось перейти на стандарт 2017 года, так как до строк с семантикой перемещения додумались только недавно.
Всё шло хорошо, пока я не дошёл до форматирования текста. В Си этим занимается функция printf, а Си++ есть метод std::format, но вот беда — он появился только в стандарте 2020 года и его ещё нет ни в одном из компиляторов, которые есть у меня под рукой.
Пошёл на поклон к ЧатГПТ, который выдал мне такую обёртку:
template<typename... Args>
std::string string_format(const std::string format, Args... args) {
int size_s = std::snprintf(nullptr, 0, format.data(), args ...) + 1; // Extra space for '\0'
if (size_s <= 0) {
throw std::runtime_error("Error during formatting.");
}
auto size = static_cast<size_t>( size_s );
std::unique_ptr<char[]> buf(new char[size]);
std::snprintf(buf.get(), size, format.data(), args ...);
return {buf.get(), buf.get() + size - 1}; // We don't want the '\0' inside
}Это так называемый «шаблонная функция». Насколько я пока понимаю принцип, компилятор смотрит с каким типами параметров вызывается эта функция, и делает их столько штук, сколько есть комбинаций вызовов.
Так как файлы с кодом друг друга не видят, чтобы шаблонная функция «знала» с какими параметрами её вызывают, её надо помещать в заголовочный файл (🤦🏻♂️), либо указать в коде все необходимые прототипы вручную (🤦🏻♂️🤦🏻♂️🤦🏻♂️).
И хотя я осознаю, что со своим уставом в чужой монастырь не лезут, первое мне кажется противоестественным, а второе — неудобным.
На этом этапе я выяснил, что мой компилятор под «Виндоуз» ничего не знает про std::string_view, а компилятор под «Мак» не может скомпилировать код выше вот с такой прекрасной ошибкой:
comm/../utils.hpp:30:60: error: cannot pass object of non-trivial type 'std::string' through variadic function; call will abort at runtime [-Wnon-pod-varargs]
int size_s = std::snprintf(nullptr, 0, format.c_str(), std::forward<Args>(args)...) + 1;Мне бы хотелось, чтобы код собирался под оба компилятора, поэтому я снова пошёл к ЧатГПТ и вернулся вот с таким прекрасным кодом:
template<typename... Args>
std::string string_format(const std::string& format, Args&&... args) {
auto size_s = std::snprintf(nullptr, 0, format.c_str(),
std::decay_t<Args>(args).c_str()...) + 1; // Extra space for '\0'
if (size_s <= 0) {
throw std::runtime_error("Error during formatting.");
}
auto size = static_cast<size_t>( size_s );
std::unique_ptr<char[]> buf(new char[size]);
std::snprintf(buf.get(), size, format.c_str(),
std::decay_t<Args>(args).c_str()...);
return {buf.get(), buf.get() + size - 1}; // We don't want the '\0' inside
}Тут происходит
comm/../utils.hpp:32:58: error: request for member 'c_str' in 'args#0', which is of non-class type 'std::decay_t<char*>' {aka 'char*'}
std::decay_t<Args>(args).c_str()...) + 1;К счастью, решилось это просто — надо было всего лишь убрать .c_str().
По пути там пришлось решить ещё пару забавных мелочей, но они недостаточно отложились в памяти, чтобы я их мог воспроизвести без опасения
Теперь я понимаю за что программистам на Си++ платят такие деньги — это доплата за нервную работу.
Благодарность Раиса
Сегодня в торжественной обстановке вручали Благодарность Раиса Республики Татарстан. Раис — это название главы нашего региона.
Электрический насос
На Новый год деловые партнёры дарили много всякого, но больше всего меня поразило вот это устройство на фотографии.
Я сначала принял его за электронный замо́к, но потом разобрался — это электрический насос. Видимо подарили, зная мою любовь к велопрогулкам.
Всю зиму и осень он лежал
Про этот насос я сам даже не вспомнил, но он мне попался, когда я искал
Называется устройство «Xiaomi Portable Electric Air Compressor 1S», если вас раздражает процесс накачивания колёс, рекомендую!
Бесплатный CLion?
Два дня до момента, когда моя среда разработки, где я мучаю Си++, превратится в тыкву. С преподавательской лицензией меня обломали, попробую другой путь — податься на бесплатную лицензию как бесплатный проект.
Казалось бы дело в шляпе, но там надо показать регулярные коммиты за три месяца, а у меня пока ещё и месяц не прошёл. Но я придумал план, надёжный, как швейцарские часы, — два месяца рефакторинга. Буду перетаскивать очевидные сишные части на Си++. Начал со строк — переписываю сишные указатели на нормальный std::string.
Придётся, видимо, пока взять в качестве редактора VSCode, вот только он не IDE. Ну а какой выбор? В процессе знакомлюсь с тем, что умеет Си++. Смотрите какая прелесть:
std::ostream &operator<<(std::ostream &os, const Colors &color) {
static const std::map <Colors, std::string> colorNames = {
{RESET, "39;49m"},
{BLUE, "01;34m"},
{GREEN, "01;32m"},
{CYAN, "01;36m"},
{RED, "01;31m"},
{MAGENTA, "01;35m"},
{YELLOW, "01;33m"},
{WHITE, "01;37m"},
{BLACK, "01;30m"},
};
os << "\033[" << colorNames.at(color);
return os;
}В Си это была большая функция с оператором switch, которая выводила на экран последовательности для переключения цвета, её надо было вызывать отдельно каждый раз. На Си++ всё удобнее:
std::cout << YELLOW << mess[2] << std::flush;Рраз и строка жёлтая. YELLOW тут у меня — значение перечисляемого типа Colors.
«Гопник-2»: демотивировался
Покупать мне её не хочется —
Дополнено: не дали:
Thank you for applying for the JetBrains Product Pack for Students.
We regret to inform you that we wouldn’t be able to provide a license due to EU and/or US export restrictions.
JetBrains as a company has to comply with all EU and US regulations and eliminate all possible risks coming out of it.
Тестовые числа
А я вот тут подумал, что в теории можно сделать такой числовой тест, который бы угадывал кто человек по профессии или какое у него хобби. Не знаю, зачем это может быть надо, но мысль мне кажется интересной.
Выдаём последовательность, просим запомнить, потом спрашиваем какие числа запомнились. Если 128, 256 — программист, 862, 1547 — историк, 235711 — математик, ну и так далее.
Мне проще запоминать числа, с которыми я сталкиваюсь или в прошлом сталкивался постоянно.
Если приезжает такси с номером 387 (номер допотопного математического сопроцессора компании «Интел»), оно у меня дольше задерживается в памяти, чем 388, хотя это соседнее число. Думаю, у остальных людей это примерно так же работает.
EE AND
У нас в подъезде висят картины, купленные, кажется, в Икее. На одной из них, мимо которой я прохожу каждое утро, есть
Такое ощущение, что на готовом эскизе случайно оказалась
Я думал, что за надписью может быть
Думаю об этом каждое утро.
Суровое пробуждение
Ваш
робот-пылесос станет бесполезнымиз-за воды, что потребует покупки нового. Вас ждет суровое пробуждение, если вы считаете, что положить мыло и моющие средства в бак не проблема.
Очень выражение понравилось. «Вас ждёт суровое пробуждение»!
Необычная вилка
Сходил к друзьям сегодня помахать металлоискателем на участке. Они недавно снесли сарай, который, по рассказам, до революции был конюшней. Была надежда найти
Похоже на вилку, но с пружинным механизмом внутри. Если нажать на шток, который справа, то перекладина на зубьях двигается. Есть упор для пальцев, как у шприца, на нём клеймо — «Москва. Артель 6я механическая — 1954г».
Несмотря на то, что эта штука пролежала в земле не одно десятилетие, коррозии почти нет.
Атрибутировать удалось с трудом. Оказалось, это столовый прибор, которым накладывают себе еду.
Синестезическая капча
Чем хороши хорошие
Синестезия — это такое «смешение чувств», когда сигналы от одного органа чувств смешиваются с другим. Например, люди начинают ощущать цвет нот. Не фантазировать на эту тему, а натурально чувствовать какой цвет у каждой ноты.
Автор книги, кажется, расширяет это определение, рассматривая синестезию как смешение любых модальностей. Например, выше иллюстрация, взятая из книги. На ней нарисованы «буба» и «кики». Это несуществующие понятия, но большинство людей, согласно эксперименту автора книги, считают, что «буба» слева, а «кики» справа.
По одной из гипотез дело тут в синестезии — смешивании ощущения от звучания слов с оптическими характеристиками рисунка.
Я подумал, что из этого могла бы получиться отличная капча, так как пока нигде нет достаточной обучающей выборки, чтобы натренировать нейросети искать в таких фигурах закономерности. Мешают две вещи.
Тем не менее, использовать в качестве капчи нечто, тестирующее нетривиальные особенности человеческого мозга, мне кажется перспективной идеей. Возможно даже более перспективной, чем капчи с эксплуатированием пиксельных атак или прочих уязвимостей алгоритмов искусственного интеллекта.