Тестирование на пользователях
В айти есть много шуток про тестирование на пользователях — когда недостаточно оттестированный или не тестируемый вовсе продукт передаётся в использование и ошибки правятся в реальном времени, по мере поступления их от пользователя.
Считается, что а) это плохо, б) это присуще исключительно айти.
Я не считаю, что это всегда плохо. Для домашних проектов это вообще, как правило, единственный путь — у меня много проектов, которые я делал в одиночку «на коленке» и выложил в общее пользование. Конечно там могут быть баги, я хоть и тестировал их, но не заморачивался прохождением всех сценариев.
Так что в пункте «а» есть много «но». А в прошлые выходные оказалось, что и пункт «б» не является абсолютной истиной.
Сфотографировал плакат, на котором рассказывается о нагрузочном тестировании зрительских места казанского цирка солдатами. Можно, конечно, возразить, что солдаты — не пользователи. Но, мне кажется, что это не совсем так.
Тот, кто профессионально занимается тестированием, от пользователя отличается одним фактором — ему платят за нахождение багов, это его работа, он от этого не страдает. Нагрузочное тестирование скамеек не является профессиональной деятельностью солдат, не думаю, что им за это заплатили и они пострадали бы, если бы «нашли баг» — если бы скамейки под ними провалились.
Сломал себе график
За школьные каникулы расслабился — дочку не надо было водить на школьный автобус, поэтому вставал на полчаса позже. Потом ещё полирнул длинными выходными и совсем сломал себе график. Когда каникулы кончились, вставать стало гораздо сложнее. Мне, сове, утро и так даётся непросто, а такие колебания совсем вышибают из колеи.
Утро третьего рабочего дня, а я чувствую себя так, как будто месяц работал круглые сутки без выходных. Видимо надо отказаться от идеи давать себе послабление в утреннем графике в школьные каникулы.
«Виселица» в каталоге программ
Нашу с дочкой игру для «Флиппера Зеро» «Виселица» включили сегодня в каталог программ для этого устройства. А ещё она есть в одной из альтернативных прошивок — от разработчика с ником RogueMaster!
Кстати, я думаю, что Ева является самым молодым соавтором игры для «Флиппера» в мире.
Сжатие инструкций для CFR[]
Выложил свою программу для перевода растра в инструкции для интерпретатора CFR[]. Написана, к слову, на «Гоу».
Самая интересная часть там — про оптимизацию.
Я реализовал довольно очевидную идею — делаем две переменные, одна указывает на начало инструкций, вторая — на середину. Вырезаем подстроку между двумя этими индексами, ищем её сразу за правым индексом, если находим, заменяем на вырезанное, оборачивая в цикл и начинаем сканировать заново. Если не находим, сдвигаем сначала правый указатель к началу, повторяем поиск, потом левый к центру, повторяем поиск. Естественно по ходу надо отбрасывать куски, где не сбалансированы скобки, это совсем просто.
Кроме того, у нас есть восемь вариантов обхода картинки — по двум направлениям из каждого угла, что, если нет симметрии, даёт восемь разных наборов инструкций, которые сжимаются
При этом немного смещается координаты отрисовки картинки. Её можно было бы возвращать обратно, но зачем? Интерпретатор и так рисует в центре холста, так что сдвиг — это не принципиально, только размер кодирующей последовательности увеличится.
Капитан Крюк
Закончили на днях читать книжку про Питера Пена и дочка решила нарисовать в 3Д крюк по мотивам. Если кто не читал или не помнит, в книжке есть капитан пиратов, у которого крюк вместо одной руки. В детстве это интригует, как я понимаю.
Интересно как быстро,
Про кости и скелеты
Когда я говорю, что иногда езжу покопать в составе
Находим, конечно, это как будто и есть основное занятие на выездах, по крайней мере на тех, куда меня приглашают. Костей не боюсь, для меня это вообще
Я, разумеется, видел как в фильмах люди вздрагивают и кричат при виде скелетов и костей, но в контексте это выглядит как испуг от неожиданного их появления.
А вы боитесь костей и скелетов? Это иррациональный страх или вы можете проследить
«Кибердеревня»
Девять лет назад я заказал кастомный свитер в компании «Свитеррариум». Свитер жив у меня до сих пор, надеваю его в походы или в холода, чтобы погулять с собакой. Не продырявился, не растянулся, но немного потерял внешний вид, что немудрено за такой срок.
С тех пор я время от времени думал заказать у этой компании
Со временем владелец компании отошёл от заказных свитеров к более массовой продукции, но из готовых изделий меня тоже
Пока сегодня у них канале не появилось объявление о распродаже свитеров с рисунком из сериала «Кибердеревня». Не то, чтобы я был большим фанатом этого сериала, но поглядываю. В основном
В общем, меня зацепило, после работы поехал примерять — ехал целый час, пробки, но очень уж хотелось приобрести. Сел, как влитой, будто на меня делался.
CFR[]
Прикольную штуку увидел на «Хабре» — минималистичный язык CFR[] для рисования картинок. Тамошнему народу
Синтаксис односимволный, C — циклическая смена цвета (доступно семь цветов), F — рисование со сдвигом по текущему направлению, R — смена направления на 45° по часовой стрелке и пара
Лучше всего таким способом рисовать
Состряпал небольшую программу, которой попереводил разные картинки в инструкции CFR[]. В ограничение до обидного мало что влезает, но небольшие надписи писать можно.
Анафема за кофе
Изучал на досуге по письменным источникам историю слов «кофе» и «кофей», ни к каким выводам не пришёл, но нашёл любопытный документ. Старообрядцам, оказывается,
В переводе на современный язык текст выглядит так:
Книга Иоанна Зонара, глава 16, лист 70. Ещё кто посмеет пить чай, тот отлучается от самого Бога и будет тоже предан анафеме, а ещё тот, кто посмеет пить кофе, в том будет коварство и лукавство, в сердце того не будет Бога и он будет предан анафеме десятикратно.
Кстати, тут, кажется, есть игра слов «кофъ» («кофе») и «ковъ» («коварство»), но возможно я
Тыквенный кальян
Прочитал тут хохму про тыквенный спас, который предлагается праздновать как альтернативу Хэллоуину. Название пришло
Народ уже вовсю облюбовал Хеллоуин, а как уж он называется — дело десятое. Тема тыквы вполне нам близка и хорошо продаётся — вчера, например, пил тыквенный латте в кофейне.
Можно развивать и дальше. Русский писатель Николай Николаевич Каразин в повести девятнадцатого века подсказывает нам идею скрестить тыкву и кальян. Впрочем, я не курю, возможно в кальянных в тыквенный спас вовсю это курят, а я просто не в курсе.
Пилю «Виселицу»
Не то, чтобы я не понимал, что сообщество владельцев «Флиппера» относительно небольшое, всё же это очень специфический инструмент, но всё же не ожидал, что написанная за выходные игрушка удостоится такого внимания.
Только выложил её на «Гитхаб», как мне написал автор одной из популярных альтернативных прошивок, прислал патч, исправляющий некую ошибку и попросил английскую версию, — хочет включить игру в свою прошивку.
Доброе слово и кошке приятно, поэтому вот уже несколько дней пилю поддержку других языков.
Для начала переделал сборку на другой инструментарий — ранее игра не собиралась через более распространённый uFBT, потому что мой код использовал
Для поддержки английского пришлось довольно много переделать, всё что осталось сейчас — вывести меню, наверное сегодня уже доделаю. Я замахнулся на конфигурируемую поддержку, по моей идее, можно будет очень просто добавить любой язык, для которого есть шрифт.
В итоге, файл описания выглядит как текстовый файл, где первой строкой написано название словаря, ниже стоит цифра, показывающая сколько букв будет выведено в строке, при рисовании клавиатуры, ещё ниже — зазор между буквами в угадываемом слове в пикселях, потом цифра, про которую я расскажу дальше, ниже — шестнадцатеричные коды букв в кодировке
Если открыть словарь для английского языка обычным текстовым редактором, то внутри будет текст, с русским такой номер не пройдёт. Объясню почему.
Когда я только начал программировать игру, начал я с упаковки русского словаря в программный код и генерации случайного слова. Оказалось, что быстро выбрать случайное слово
В словаре так и сделано. Поскольку внутри программы я храню различные состояния в виде массива, мне нужно знать минимальный получившийся код символа, чтобы вычитать его, преобразовывая код в смещение в массиве. Для русского языка минимальный код будет у буквы А — 0x10, как я показывал выше, то его и нужно записать в файл описания языка. Цифра 16 в нём — это и есть 0x10 в десятичной кодировке.
Надеюсь сегодня допишу всё что нужно и выложу новый вариант.
«Электричка»
В последние лет пятнадцать слово «электричка», в значении «электропоезд» постепенно исчезало из лексикона людей в моём круге общения. Я сам на электричке в последний раз ездил
Цифровая диета
Заметил за собой одну проблему — чрезмерное увлечение листанием лент как будто выжигает во мне всю творческую энергию и непропорционально расходует время. В моём случае такой эффект имеют «Пикабу» и короткие истории «Ютуба», больше я нигде так не залипаю.
В этом году несколько раз проверил на себе — стоит запретить себе времяпрепровождение в подобных местах и у меня как будто даже жизнь меняется. Появляется время для своих интересных проектов, а главное — идеи и желание их реализовывать.
Стоит, по всей видимости, задуматься об упорядочивании потребления информационной нямки и сесть
Написали с дочкой игру
После того как я обнаружил, что на «Флиппере Зеро» можно писать программы с поддержкой русского языка, никак не мог отделаться от желания написать
Раздумывал недолго, выбрал для реализацию игру «Виселица» (некоторые знают её под названием «Балда»), в которую
Правила там простые — один игрок загадывает слово и рисует чёрточки по количеству букв в нём. Второй пытается отгадать побуквенно. Если названная буква в слове есть, на бумаге рисуется позиция или позиции этих букв, если нет, то рисуется часть виселицы. Если виселица нарисована полностью, отгадывающий проиграл, если слово угадано раньше, — выиграл.
Пока программировал, подсела дочка, спросила чем я занимаюсь, я рассказал с примерами. Мы даже пару раз сыграли на бумаге, после чего вызвалась мне помочь нарисовать графику к игре.
Я подумал, что вполне смогу использовать то, что она нарисует в прототипе, но получилось вполне симпатично и я оставил её графику как есть.
Так что у нас с дочкой теперь есть первая совместная игра — я программировал и разрабатывал интерфейс, она нарисовала виселицу и иконку приложения, а так же выступила первым тестером.
Пишем на «Флиппере Зеро» по-русски
★
Вкратце: в русским текстом работать можно, но сложно, код лежит на «Гитхабе».
Не мог не обратить внимание, что несмотря на приличное количество русскоязычных авторов программ для «Флиппера Зеро» и российское происхождение устройства, в софте под него нигде не обнаружилось ни одной буквы
Стало интересно — а есть ли вообще в устройстве поддержка русского языка? Сел вечерком за исходники прошивки и оказалось, что однозначного ответа на заданный вопрос нет. Частичная поддержка есть и её можно заставить работать, но она работает как будто по недосмотру — никто её не собирался делать, так случайно вышло.
Сейчас расскажу, что я имею ввиду и постараюсь покороче, никто сейчас не любит длинные тексты.
Внутри «Флиппера» довольно много всякого АПИ для вывода текста, от незатейливого, выводящего строку в заданные координаты, до довольно навороченного, умеющего переносить и выравнивать текст. К сожалению, с русскими буквами оно работать не умеет.
Под капотом у этого АПИ — очень известная в своей нише библиотека U∞g2, у которой по историческим, видимо, причинам есть два набора функций для работы со строками. Одни принимают только однобайтовую кодировку ASCII, другие работают в Юникоде.
АПИ «Флиппера», к сожалению, использует функции, которые с Юникодом работать не умеют. К счастью,
Первый из них — canvas_set_custom_u8g2_font.
Чтобы
Вот как я это делаю:
#include <u8g2/u8g2_fonts.c>
// …
canvas_set_custom_u8g2_font(canvas, u8g2_font_haxrcorp4089_t_cyrillic);Файл u8g2/u8g2_fonts.c внутри себя содержит шрифты в особом формате, можно открыть его прямо в текстовом виде и посмотреть как всё устроено.
Шрифт мы выбрали, теперь надо
Плохая новость в том, что строки в коде мы обычно пишем в кодировке
Но canvas_draw_glyph, как можно понять из названия, выводит только один символ. Как же вывести строку? Достаточно просто — надо вывести её посимвольно, сдвигая координату на ширину символа. Звучит просто, но как это сделать?
Тут нас ждёт очередная засада. Дело в том, что canvas_glyph_width, которая должна бы это делать, принимает на вход только char, при том, что нижележащая u8g2_GetGlyphWidth преспокойно работает с Юникодом.
Поэтому я сделал просто — выдрал реализацию u8g2_GetGlyphWidth себе в исходники. В итоге мякотка моего решения выглядит вот так:
void unicode_draw_utf8_str(Canvas* canvas, uint8_t x, uint8_t y, char* str) {
FuriStringUTF8State state = FuriStringUTF8StateStarting;
FuriStringUnicodeValue value = 0;
for(; *str; str++) {
furi_string_utf8_decode(*str, &state, &value);
if(state == FuriStringUTF8StateError) furi_crash(NULL);
if(state == FuriStringUTF8StateStarting) {
canvas_draw_glyph(canvas, x, y, value);
x += unicode_GetGlyphWidth(&canvas->fb, value);
}
}
}Тут unicode_GetGlyphWidth — скопированная реализация u8g2_GetGlyphWidth, а furi_string_utf8_decode используется для кодирования
Куртка с подогревом
К сожалению, китайские размеры — та ещё лотерея, не повезло — рукава оказались слишком короткими.
Поскольку куртка стоила
Сказано — сделано!
На днях протестировал получившуюся жилетку с подогревом. К сожалению, результат функционирует ровно на свою цену. Не особо греет на улице — зоны подогрева слишком маленькие, зато бесполезно поджаривает спину и бока в машине, когда сидишь плотно прижав своим весом нагревательные элементы к телу.
Буду носить как обычную жилетку, хоть
Кхе-кхе
Как «испанка», мутировав, полностью растворилась в других заболеваниях, так и ослабевший Ковид уже никого всерьёз не беспокоит — в мире ходят
Интересно, что вокруг стало
Все, с кем я об этом говорил, предполагают, что это
Моя первая программа под Flipper Zero
Вчера вечером
Как я уже писал, документации на удивление мало, пришлось налегать на чужие исходники. Если касаться темы прокрутки экрана, то, по всей видимости, существуют два способа: перерисовывать экран самостоятельно, вызывая каждый раз компонент полосы прокрутки с нужным значением или заморочиться с созданием так называемой «сцены», разместить на ней виджет прокручиваемого текста и засунуть туда весь текст, который надо прокручивать, целиком.
Второй способ больше подходит для многоэкранных приложений, поэтому его я не выбрал — для моих целей там слишком много мороки. Поэтому в этой части всё получилось достаточно просто:
void beer_render_callback(Canvas* canvas, void* ctx) {
// …
elements_scrollbar(canvas, BEER_MAX - pos, BEER_MAX + 1);
// …
}
int32_t beer_main(void* p) {
// …
switch (event.key) {
case InputKeyDown:
if (app->pos > 0) app->pos--;
break;
case InputKeyUp:
if (app->pos < BEER_MAX) app->pos++;
break;
default:
break;
}
view_port_update(app->view_port);
// …
}В цикле опроса клавиатуры ловим клавиши «вверх» и «вниз», в соответствии с клавишей увеличиваем или уменьшаем счётчик, после чего вызываем перерисовку, в коллбеке которой выводим экран и полосу прокрутки с правильной позицией.
Возможно сделаю ещё автоскроллинг экрана на длинное нажатие клавиши, но пока не уверен, что мне хочется — может лучше
Программирую под Flipper Zero
Мне месяц назад на день рождения подарили «Флиппер Зеро» — «перочинный ножик для хакера». Довольно известное в узких кругах устройство, очень занятное. Но об этом
Давно подмывало
В интернете есть несколько статей о том как начать, которые мне очень помогли. Довольно быстро я научился собирать первое приложение, которые выводит строчку текста и опрашивает клавиатуру. По пути поразился сколько бойлерплейта (шаблонного почти одинакового для каждого приложения кода) пришлось написать. Очень не хватает
Пока застопорился — не пойму как прокручивать экран и есть ли
Железный лом
Месяц назад рассказал в одной компании о том, что в некоторых районах Татарстана люди промышляют добычей чёрного металла из земли. Ходят с металлоискателями, иногда даже самодельными, выкапывают всякое и сдают в пункты приёма металлолома.
Я одного такого человека даже лично знаю, а ещё несколько видел за работой издалека, когда ездил по сёлам по делам военного поиска или к друзьям, покопать старину в огородах.
В общем, пришлось к слову, рассказал, а в ответ меня огорошили тем, что килограмм металла стоит меньше двадцати рублей. Я тогда в первый раз всерьёз задумался о том сколько именно металла надо проволочь, чтобы хотя бы окупить бензин.
Сегодня опять об этом вспомнил.
Гуляя с собакой я обычно прохожу мимо кустарного забора, сделанного из старых металлических спинок кроватей, залитых цементом. А сегодня обратил внимание, что