Можно ли сделать деревянный стеллаж без инструмента используя только отвертку и 3D-принтер? Легко!.

Приветствую! Я хочу поделиться с вами очередной своей разработкой, которая позволяет сделать надежную, крепкую мебель и при этом без необходимости иметь инструмент, пылить в доме/квартире и собрать её буквально за один день. Эта статья для аудитории Хабра, которая любит DIY и получает удовольствие от процесса создания вещей своими руками. Осторожно, в статье много изображений и фотографий.

▍Началось все с …

Попросила меня супруга сделать небольшой открытый стеллаж на кухню чтобы всё было недалеко и при этом у всего было своё место. Подумал я, что делать «просто ящик» прямоугольной формы не хочу – это не красиво и будет выглядеть как коробка… Рядом с местом предполагаемой установки стоит буфет Хемнэс от ИКЕА. Посмотрел я на него и мне понравился стиль его боковых стенок – по углам брусок, а в середине филёнка. 
Да, это не стеллаж, но на этой фотографии лучше видно то, о чем я пишу:

Ну думаю надо делать по такой технологии, однако почти сразу понял, что данная сборка возможна только если фрезеровать ножки и вклеивать в паз филенку. У меня есть фрезер и место где это можно сделать, но работать с ним я жуть как не люблю, а люблю работать с SolidWorks и разрабатывать что-либо для печати на 3D-принтере. Поэтому было принято решение разработать детали, с помощью которых можно собрать аналогичную конструкцию, но без фрезеровки, сверления, запилов и прочей грязной работы. Наша цель – максимально снизить необходимость в обработке дерева на территории дома.

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

▍Разработка

Сел за Solid, сделал пару деталей и понял, что «это всё не то», надо их унифицировать.  Поэтому я на время отложил Solid и пошел по интернет магазинам смотреть какие типовые размеры бывают у мебельных щитов.

В итоге с чем нам придется работать:

  • Толщина которая нас интересует – 18 мм
  • Доступные ширины – 200 / 250 / 300 / 400 / 500 / 600 мм
  • Длина от 600 до 3000 мм
  • Брусок на ножки взят такой, как у Хемнэс – 40х40 мм

Задача и вводные данные ясны, оттягивать не стоит, нужно делать.

За типовой размер взяты Х-мм на филенку и Х+50 мм на полку. Сделано это неспроста. Допустим мы используем филенку размером 200 мм, соответственно общая ширина боковой стенки будет равна 280 мм. Делать полку 300 мм не получится, так как она будет шире самой стенки и будет выпирать. Во вторых, красивее, когда полка чуть утоплена внутрь, а не заподлицо с боковой стенкой – это создает эффект объема и убирает эффект «ящика». Соответственно среди типовых размеров в продаже у нас есть щиты размером 250 мм. Вот его мы и будем использовать для разработки общей конструкции деталей.

Если же мы хотим стеллаж глубиной 380 мм, то мы берем щит 300 мм на филенку и 400 мм на полки, НО! в этом случае нам просто нужно при покупке распилить щит вдоль, отрезав 50 мм, а потом поперек на длину равную длине полки.
 
Некоторое время на работу и в итоге у меня получился набор из 6 уникальных деталей, которые позволяют собрать конструкцию любой длины. Некоторые детали различны для стартовой/финишной и промежуточных стенок. Схема стеллажа, расположения деталей и их названия показаны на схеме ниже:

Деталь panel_rack_bracing крепится к каждой полке и нужна для придания конструкции жесткости, а также связывания нижней части. Без нее ножки не разъедутся, но конструкция не получится крепкой.
Детали в крупном виде под спойлером. Подписывать каждую не буду, они легко находится на схеме выше.

Фото деталей крупно






▍Как это работает

Сейчас я опишу технологию сборки на примере небольшой конструкции.
Допустим мы хотим получить столик-стеллаж глубиной 300 мм, высотой 1000 мм и длиной 1200 мм. В стеллаже должно быть 6 полок.

Покупаем в строительном магазине (Леруа / Максидом / OBI / …):

  • брусок на ножки – 40х40х2000 мм в кол-ве 4 штуки
  • щит на столешницу – 12х300х1200 мм (стандартный размер)
  • щит на филенку – 18х200х800 мм в кол-ве 3 штуки
  • щит на полки – 18х250х2000 мм

Набираем это всё, идем на распиловку и просим распилить каждый брусок на ножки по 980 мм, а щит для полок на 6 штук по 330 мм.

Там же берем саморезы с пресс-шайбой («клопы») размером 4,2х13 и саморезы с потайной головкой 4,0х30. Вторых нужно будет равным количеству нижних полок умноженное на 2. А вот первых нужно будет намного больше. Считать лучше из общего количества пластиковых деталей умноженного на 2,5.

Распечатываем на 3D-принтере:

  • 40x40_top – 8 шт
  • 40x40_btm_right_shelf – 2 шт.
  • 40x40_btm_left_shelf – 2 шт.
  • 40x40_btm_2sides_shelf – 4 шт.
  • panel_rack_bracing – 6 шт.
  • rack_holder – 12 шт.

На бруски надеваем верхний элемент, прикручиваем к бруску. Затем нижний (в соответствии со схемой), а в середину филенку. Всё плотно прижимаем и скручиваем. Получается такая конструкция стенки:

Далее к середине нижних полок прикручиваем держатель panel_rack_bracing

Столешницу лучше разметить на полу и через специальные отверстия прикрутить к ней ножки, а затем нижние полки. Всё, изделие собрано! Процесс сборки занимает реально очень мало времени – у меня на сборку данного стеллажа ушло не более 30 минут. Из необходимого инструмента только шуруповерт или отвертка.
 
Вот что у нас получилось и как оно выглядит в интерьере


 

▍Дополнительные возможности

Первый плюс данной конструкции мы рассмотрели выше – нам ничего не нужно пилить / сверлить / фрезеровать. При определенных длинах полок даже нет необходимости в распиловке в магазине.

Второй же плюс в том, что данная система позволяет собирать стеллажи любой длины. Ранее мы собрали стеллаж длиной 1,2 м, однако мы легко можем собрать такой же стеллаж но длиной 2, 3 и даже 5 и более метров (при условии соединения столешницы на штапики). При этом жесткость конструкции будет аналогичной.
 
И наконец третий плюс – сборка стеллажа в высоту и возможность делать комбинированные сборки, когда одна секция ниже другой. Сейчас я собираю конструкцию в спальню дочери, где одна секция будет глубиной 380 мм (филенка 300 мм, полки – 350 мм), а вторая – 280 мм. При этом глубокая секция высотой 2,7 м (обязательно крепить к стене или потолку), а низкая – 1,6 м.

Большая секция в процессе сборки:

Внимательный читатель наверное уже заметил, что здесь появилась новая, 7/8/9-я детали. Эти детали держат филенку в середине её длины, центрируют относительно ножки и притягивают к ней. Они немного отличаются от нижних стартовых отсутствием поддерживающей полочки.

Выглядят они следующим образом:



Собственно думаю на этом статью можно закончить и поделиться с вами моделями.
Полный набор файлов для печати выложены на Thingiverse

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

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


ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/562592/

Культура разработки ПО слишком позитивна, это может нам вредить

image

Кажется очень странным писать о том, что нечто может быть слишком позитивным. Однако я начал замечать, что многие проблемы разработки ПО могут возникать из-за людей, которые слишком позитивны или влюблены в своё дело. Позвольте объяснить.

Выгорание

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

В этом году я много общался с людьми, не связанными с технологиями, и заметил одну вещь: мы не особо жалуемся на свою работу. Мы жалуемся на плохое руководство и плохие проекты, но не на сам кодинг. Мы воспринимаем горение своей работой как нечто само собой разумеющееся. Вы удивлены? Почитайте вакансии. Любовь к работе — часто одно из обязательных требований. От нас ждут, что мы будем любить свою работу, более того, что мы сделаем программирование центром своей вселенной.

Но как насчёт людей, которые не любят программирование, но всё же хорошо справляются со своей работой? Попробуйте сказать своим коллегами или в Twitter, что вы один из них, и вас сразу же заклеймят как плохого разработчика. Однако на самом ли деле это так? Люди, которые делают свою работу, а после работы занимаются чем-то другим, тоже могут быть потрясающими программистами. Не каждый обязан приходить домой и трудиться над хобби-проектами, писать посты в блог, записывать видео в YouTube о кодинге и читать книги о программировании.

Я был одним из тех людей, которые пытаются всё своё свободное время работать. Многие годы я чувствовал вину за то, что не трачу всё время на преследование какой-то воображаемой продуктивности. Догадайтесь, к чему это меня привело?

Новые блестящие игрушки

Ещё один аспект, в отношении которого негатив воспринимается в штыки — это отношение к новым трендам, создаваемым компаниями уровня FAANG. Попробуйте сказать что-нибудь против SOA или Docker. Попробуйте предложить более взрослый и зрелый язык или SSR. Это аналогично ситуации со страстью к работе. Люди мгновенно заявят, что ты плохой разработчик, потому что ты «препятствуешь прогрессу».

Не у всех работают тысячи микросервисов, как у Uber, и не каждой компании требуется K8S. Однако сложно удержаться от всеобщего энтузиазма, или хотя бы не делать вид, что ты его разделяешь. Скольким организациям не удалось мигрировать на React или Angular? В результате они получили кодовую базу, разделённую на старый «плохой» код, который работает, и новый код, который разработчики пытаются заставить работать.

Эта недавняя статья показывает реальность многих организаций: I Almost Got Fired for Choosing React in Our Enterprise App

Best Practices

Когда я был техлидом, то часто слышал фразу: «потому что это хорошая практика». Затем я начинал задавать вопросы и замечал, что сказавший это человек не полностью понимает решение. Это была моя лакмусовая бумажка, позволяющая узнать, что нужно копать глубже.

Какие из этих «универсальных» best practices на самом деле не универсальны? DRY (Don’t Repeat Yourself) часто упоминается в одном предложении с KISS (Keep It Simple Stupid), хотя часто они являются взаимоисключающими практиками. «Simple» означает отсутствие необязательных абстракций, однако если начинать сразу с DRY-кода, то он и ведёт к преждевременным абстракциям.

Лично я пользуюсь правилом 3X:

«У нас есть одержимость многократным использованием. Но не корите себя за это, это эндемичное заболевание среди разработчиков ПО. Даже, пожалуй, профессиональная болезнь.

— Многократно используемые компоненты создавать в три раза сложнее, чем одноразовые

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

Разумеется, я не считаю это абсолютной истиной. Скорее, это эмпирический закон, чем хорошая практика. Но даже здесь мы сталкиваемся с той же проблемой. Люди, которые осмеливаются предложить использовать синглтон или любой другой ненавидимый антипаттерн, воспринимаются как не очень хорошие разработчики.

Подведём итог

Ожидание, что личность настоящих разработчиков ПО, хакеров и гиков должна определяться их профессией, напоминает какую-нибудь RPG. Твоя специализация определяет тебя навечно, и после того, как ты выбрал свой путь, дороги назад нет.

От нас, разработчиков, ожидают, что мы должны любить программирование. Но почему? Истина проста: это хорошо для работодателей. Сколько ужасных историй мы слышали из геймдева? Тем не менее, множество молодых людей мечтает о работе в игровой индустрии, хотя спустя несколько лет их заменят на новую поросль наивной молодёжи.

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

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

Я хочу пробовать что-то другое, и это совершенно нормально.


На правах рекламы

Наша компания предлагает аренду VPS для совершенно любых проектов. Создайте собственный тарифный план в пару кликов, максимальная конфигурация позволит разместить практически любой проект — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe!

Подписывайтесь на наш чат в Telegram.

ссылка на оригинал статьи https://habr.com/ru/company/vdsina/blog/562634/

Мой штрихкод. Code128

Однажды в процессе производственной деятельности у меня появилась необходимость генерации штрихкода по стандарту code128. Появилась в виду того, что имевшаяся в эксплуатации функция (хранимая процедура в базе Oracle) генерировала клёвый, полосатый штрихкод, который читался не во всех случаях. Разработчики в своё время оттестировали эту процедуру весьма некачественно, но перерабатывать уже не собирались т.к. проект был давно сдан, а потребности в считывании так и не появились.

Первая мысль — поиск готовых библиотек. Навскидку определили критерии — с pl/sql не связываемся, пусть это будет внешний сервис: возможно кусок на javascript для генерации прямо на страничке, либо обращение за картинкой к ближайшему серверу где имеется php. Беглый поиск в интернете показал что тема истоптана весьма плотно. Есть как наколенные поделки уровня лабораторки по программированию, так и мощные библиотеки для всех вариантов кодирования вплоть до qr-кодов. Варианты с JavaScript пришлось отбросить т.к. они во-первых практически все «обфусканы» (даже непонятно, то ли для сокращения объема, то ли стыдно исходники показать), во-вторых генерируют строку для отображения определенным шрифтом, наличие которого не всегда можно обеспечить на клиентском месте и требует дополнительных обработок для экранирования спецсимволов. Внимательное изучение библиотек и кусков кода на php тоже произвело тягостное впечатление — на первый взгляд всё вроде бы правильно: и классы написаны на все случаи жизни, комментарии в наличии, украшательства типа выбора цвета и рамочек, примеры подготовлены. Начнёшь вникать — хотят либо php самой распоследней версии (на боевых серверах не всегда это получается добыть), либо внутренняя логика не различима совсем, либо штрихкод на выходе получается длиннее ожидаемого. Вот последнее не дало покоя и подтолкнуло к собственной реализации.

Самое время пощупать теорию. Вернее мы с ней познакомились намного раньше, просто до последнего не хотелось ввязываться в дополнительное программирование. Исторические факты опустим, а вот очень хорошее техническое описание имеется на http://code128.narod.ru/ (в архиве это файл Descript.doc ) либо в Википедии. В принципе, это всё что нам потребуется для понимания и собственной реализации алгоритма (тут я немного лукавлю — из любой готовой библиотеки нужно выдрать таблицы толщин штрихов, чтобы не вбивать их вручную). Ну и напишем всё это безобразие на php, заодно посмотрим пару прикольных моментов, про которые все забывают или стесняются использовать.

Теория гласит, что code128 позволяет закодировать (сюрпрайз!) 128 символов, при этом нам доступно 3 алфавита, между которыми можно переключаться по ходу дела. Наибольший практический интерес представляют алфавит «B» для буквенно-цифровых символов и алфавит «С» который используется для кодирования цифр, но с некоторой оптимизацией — одним штриховым символом можно закодировать 2 исходных символа и получить более короткий штрихкод. Вот эта оптимизация пока не даётся ни одному php-разработчику — максимум что я видел это попытка в начале кодирования определить состав строки и при наличии только цифр переключаться на алфавит «С». В остальных библиотеках это банальная подстановка символов штрихкода по таблице.

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

Разберём пару примеров. Допустим у нас есть последовательность «ABC12DE» попробуем её закодировать разными методами, на примере изображены слева только алфавит B, справа — совместно B и С:

Наша попытка оптимизировать длину кода используя более короткий алфавит потерпела фиаско — мы получили дополнительные символы на переключениях алфавита и в результате штрихкод стал на 1 символ длиннее. Если хорошо подумать, то переключение на алфавит С выгодно при наличии 6 и более цифр подряд. Но есть ведь и граничные случаи — цифры в конце последовательности, в начале, а есть еще вариант с нечетным количеством цифр и тогда надо пристально смотреть когда переключаться на алфавит С — с первой цифры или со второй? В общем вариантов достаточно много, что в итоге у большинства отбивает желание оптимизировать длину кода, а делать всё одним алфавитом.

И вот тут нас озаряет, что работа с рекурсивной функцией избавит нас от рассмотрения всех этих условий и задача станет невероятно простой — функция будет вызывать сама себя с тремя вариантами кодирования текущего символа и возвращать наиболее короткий (итоговый) вариант. Причём длина варианта включает в себя и символ переключения между алфавитами. Причин отказа от захода в ветку алгоритма совсем немного — либо кончился входной поток, либо мы не можем закодировать символ(ы) данным алфавитом (например нет 2-х цифр для алфавита «С»). Так, как входной поток имеет ограничение по длине, то дерево не будет расти бесконечно! По тексту будем реализовывать только алфавит «B» и «C» — проще для понимания и потом объясню остальное 🙂

Сразу набросаем простейший класс который содержит сам текст, такие-же классы для рассмотрения вариантов по алфавиту B и С, длину последовательности. Делаем ему минимальный конструктор — на входе строка для кодирования, режим кодирования, ссылки на потомков. В начале конструктора добавляем проверки, чтобы не прорабатывать данную ветку дерева:

<?php  class code128 {     private $code = '';     private $leafB = NULL, $leafC = NULL;      public function __construct($text, $mode = 'B')     { 			if (strlen($text) == 0) return NULL;  			$this->mode = $mode;  			if ($mode == 'B') { 	    		$this->code = substr($text, 0, 1); 	    		$text = substr($text, 1); 			} 			else if ($mode == 'C') { 	    		if (strlen($text) < 2) return NULL; 	    		if (!is_numeric($text[0])) return NULL; 	    		if (!is_numeric($text[1])) return NULL;  	    		$this->code = substr($text, 0, 2); 	    		$text = substr($text, 2); 			} 			else	 	    		return NULL;  			$this->leafB = new code128($text, 'B'); 			$this->leafC = new code128($text, 'C');     }      public function draw()     { 				echo "Code [" . $this->code . "]\n"; 				if ($this->leafB != NULL) $this->leafB->draw(); 				if ($this->leafC != NULL) $this->leafC->draw();     } }      $n = new code128('s92317lsdfa4324', 'B');     $n->draw(); ?>

и сразу ловим конкретный косяк — куча «пустых» объектов. И это не смотря на то что мы явно отказались создаваться и вроде как железно возвращаем NULL! В общем сразу надо понять, что в php объект создаётся в любом случае. Полагаю что также и в остальных объектно-ориентированных языках. И все эти условия надо проверять перед созданием объекта. Следовательно правильный конструктор будет выглядеть примерно так:

    public function __construct($text, $mode = 'B')     { 			$this->mode = $mode;  			if ($mode == 'B') { 	    		$this->code = substr($text, 0, 1); 	    		$text = substr($text, 1); 			} 			else if ($mode == 'C') { 	    		$this->code = substr($text, 0, 2); 	    		$text = substr($text, 2); 			}  			if(strlen($text)>0) $this->leafB = new code128($text, 'B'); 			if(strlen($text)>1) 	    		if(is_numeric($text[0]) && is_numeric($text[1])) $this->leafC = new code128($text, 'C');     } 

Не считая того, что мы избавились от пустых объектов, код получился даже немного короче чем прототип. Дальше начнём немного оптимизировать — добавим небольшой трюк: вместо того чтобы делать кучу проверок является ли последовательность символами, цифрами, их количество и т.д. просто смотрим в таблице наличие такого индекса в алфавите. Я уже писал что таблицу можно добыть в любой библиотеке реализующей кодирование code128? В общем напоминаю ещё раз, и готовый кусочек кода, который мне уже нравится, приведен ниже:

	if($mode == 'B') list($this->code, $text) = sscanf($text, '%c%s'); 	if($mode == 'C') list($this->code, $text) = sscanf($text, '%2d%s');  	if(strlen($text)>0) 	    if(array_key_exists(substr($text, 0, 1), $symCode)) $this->leafB = new code128($text, 'B', $this); 	if(strlen($text)>1) 	    if(array_key_exists(substr($text, 0, 2), $symCode)) $this->leafC = new code128($text, 'C', $this);

$symCode — это алфавиты, которые я загнал в файл tables.php и включаю его через require в начале исходника. Формат простой — символ алфавита => код штрихкода.

$symCode = array( /*	alphabet B	alphabet C */ 	' ' => 0,	'00' => 0, 	'!' => 1,	'01' => 1, 	'"' => 2,	'02' => 2, 	'#' => 3,	'03' => 3, 	'$' => 4,	'04' => 4, 	'%' => 5,	'05' => 5, 	'&' => 6,	'06' => 6, 

Дерево строится, но результата пока не видно. Следующим этапом необходимо определить самую короткую ветку: Первый вариант — заводим в классе счётчик и увеличиваем его при каждом переходе на ветку. Как только достигнем дна (конца исходного текста), на концах дерева будет указан размер финального кода. Второй вариант — конечные веточки ставят себе размер 1, а дальше родитель решает какой из потомков имеет код короче и ставит себе размер на 1 или 2 больше. Почему на 2? Надо учитывать накладные расходы на переключение алфавита. Кстати и в первом варианте это тоже надо учитывать. В итоге в корне дерева будет длина самой короткой последовательности. Чем хорош первый вариант? Получение итоговой последовательности практически мгновенное — возвращаешься «по папе» к корню дерева. Ну и недостаток — чтобы найти самую короткую ветку надо сделать полный обход дерева. Второй вариант — длина самой короткой последовательности известна и находится в одном месте, но получение последовательности чуток посложнее, хотя и не требует полного обхода. Попробуем проработать первый вариант — доделать надо совсем немного, просто родитель после создания потомков должен выбрать самого короткого потомка и сохранить ссылку на конечный элемент ветки. Выразился невероятно коряво, но Вы посмотрите код — там ещё страшнее 🙂

require 'tables.php';  class code128 {     private $code = NULL;     private $text = '';     private $mode = 'Auto';     private $len = 1;     private $leafB = NULL, $leafC = NULL, $parent = NULL, $minCode = NULL;      public function __construct($text, $mode = 'Auto', $parent = NULL)     { 			global $symCode; 			$this->parent = $parent; 			$this->text = $text; 			$this->mode = $mode;  			if($parent != NULL) { 	    		$this->len = $this->parent->len + 1; 	    		if($this->parent->mode != $mode) $this->len++; 	     }  	    if($mode == 'B') list($this->code, $text) = sscanf($text, '%c%s'); 	    if($mode == 'C') list($this->code, $text) = sscanf($text, '%2d%s');  	    if(strlen($text)>0) 	       if(array_key_exists(substr($text, 0, 1), $symCode)) $this->leafB = new code128($text, 'B', $this); 	    if(strlen($text)>1) 	       if(array_key_exists(substr($text, 0, 2), $symCode)) $this->leafC = new code128($text, 'C', $this);  	    if($this->leafB == NULL && $this->leafC == NULL) $this->minCode = $this; 	    else { 	       $this->minCode = ($this->leafB != NULL) ? $this->leafB->minCode : $this->leafC->minCode; 	       if($this->leafC != NULL) 		        if($this->minCode->len > $this->leafC->minCode->len) $this->minCode = $this->leafC->minCode; 	    }  	    return $this;      } 

Итак, худо-бедно мы нашли самый короткий путь (штрихкод). Надо его вывести для начала на экран. Делаем в два этапа: сначала от потомка возвращаемся к родителю. Итоговые символы, включая переключение между алфавитами, пушим (push) в массив. Да, в PHP есть такая функция, и она позволяет нам сделать из массива довольно удобный стэк.

 private function getCode()  { 		$stack = array(); 		$p = $this->minCode;  		while($p != NULL) { 	    	array_push($stack, $p->code);  	    	if($p->parent != NULL) { 						if($p->parent->mode == 'Auto') { array_push($stack, 'Start'.$p->mode); break;} 						if($p->mode != $p->parent->mode) array_push($stack, 'Code'.$p->mode); 	    	}  	    	$p = $p->parent; 		}  		return $stack;   }

Когда потребуется вывести строку — используем array_pop. Таким образом, мы по прежнему используем данный массив как стэк и легко выводим информацию в обратном порядке. Попутно готовим дополнительную обвязку для нашего штрихкода — старт/стоп/контрольная сумма.

Финал совсем близко — я уже устал писать, Вы устали читать. Предлагаю пробежаться весьма бегло. Само рисование сделано в виде SVG. Для данной задачи весьма удобно — нет необходимости кодировать размеры изображения, они будут задаваться тэгами на страничке. Кроме того, рендеринг и масштабирование осуществляется конечным устройством, что обеспечит необходимое качество в dpi соответствующее устройству вывода.

  private function printPattern($code, $posX, $res, $height)   { 		for($i = 0; $i < strlen($code); $i++) { 	    	$w = $res*intval($code[$i]);  	    	if(!($i%2)) 						echo "  <rect x='$posX' y='0' width='$w' height='$height' fill='#0'/>\n";  	    	$posX += $w; 			}  			return $posX;    }     public function printSVG($resolution=1, $height=50)    { 			global $symCode; 			global $barPattern;  			$s = $this->getCode();  			$pos = 1; 			$offset = $resolution*11; 			$width = ((count($s) + 4)*11 + 2)*$resolution;  			echo "<svg xmlns='http://www.w3.org/2000/svg' width='$width' height='$height'>\n";  			$start = $symCode[array_pop($s)]; 			$checksum = $start;  			$offset = $this->printPattern($barPattern[$start], $offset, $resolution, $height);  			while(!empty($s)) { 	    		$code = $symCode[array_pop($s)]; 	    		$offset = $this->printPattern($barPattern[$code], $offset, $resolution, $height); 	    		$checksum += $code*$pos; 	    		$pos++; 			}  			$offset = $this->printPattern($barPattern[$checksum%103], $offset, $resolution, $height); 			$offset = $this->printPattern($barPattern[$symCode['Stop']], $offset, $resolution, $height);  			echo "</svg>\n";     } 

Появился глобальный массив $barPattern. Искать в файле tables.php рядом с $symCode. Кусочек приведу. Там всё просто — для заданного кода выходного символа чередуются толщины черных и белых штрихов:

$barPattern = array( 	'212222',	/* 0 */ 	'222122',	/* 1 */ 	'222221',	/* 2 */ 	'121223',	/* 3 */ 	'121322',	/* 4 */

Как этим пользоваться? В файл с классом в конец добавим пару строк:

    header('Content-Type: image/svg+xml');     echo "<?xml version='1.0' encoding='UTF-8' standalone='no'?>\n\n";      $n = new code128(html_entity_decode($_SERVER["QUERY_STRING"]));     $n->printSVG();

попробовать можно сразу, вставив в html-страничку примерно вот такой тэг:

<img src="barcode128.php?ad32324adsFAE13413ldsFf">

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

ссылка на оригинал статьи https://habr.com/ru/post/562642/

Открылся набор в Indie Games Accelerator и Indie Games Festival от Google Play

Indie Games Accelerator и Indie Games Festival – две программы для независимых (инди) разработчиков мобильных игр, организованных командой Google Play. Программы направлены на то, чтобы помочь небольшим игровым студиям и разработчикам стать популярнее в Google Play независимо от того, на какой стадии находятся их проекты.

В этом году обе программы пройдут в онлайн-формате, заявки принимаются до 1 июля – подробности под катом.

Для нас важно поддерживать не только крупные международные компании, но и небольшие инди-команды – благодаря своей креативности и увлеченности играми, они создают уникальные и интересные проекты. Если вы работаете над уникальным проектом и хотите, чтобы о нем узнал мир, предлагаем вам принять участие в одной (или обоих сразу) из наших программ — Indie Games Accelerator и Indie Games Festival

Каждая из программ направлена на то, чтобы помочь небольшим игровым студиям стать популярнее в Google Play независимо от того, на какой стадии находятся их проекты: в акселератор принимаются проекты на этапе идеи или прототипа, фестиваль подойдет для игр, находящихся в активном оперировании. Заявки на обе программы принимаются до 1 июля. 

Indie Games Accelerator: обучение и менторская поддержка

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

Проекты, которые пройдут отбор и станут участниками акселератора, смогут присоединиться к 12-недельной образовательной программе, а также получат возможность поработать над своими проектами вместе с экспертами из Google, крупных игровых студий и венчурных фондов. Rovio, Game Insight, Zynga, Play Ventures, Unity Technologies, Belka Games – с полным списком менторов и условиями участия можно ознакомиться здесь.

В этом году в акселерационной программе участвуют более 70 стран, – заявки на Indie Games Accelerator из России, Украины и Беларуси будут приниматься впервые!

Indie Games Festival: промо-кампании для финалистов

Эта программа разработана для небольших команд, которые недавно выпустили игру и хотят дальше работать над проектом без помощи паблишера или инвесторов. 

Основные критерии отбора: инновационность, увлекательность и дизайн. Среди призов: фичеринг на Google Play и промо-кампании для 3 игр-победителей стоимостью 100 000 евро.

Условия участия: в программе участвуют 29 стран Европы, включая Россию, Украину и Беларусь; максимальное количество человек в команде – 50, игра должна быть выпущена на Google Play не ранее 3 марта 2020 г. Подробнее с правилами участия и критериями отбора можно ознакомиться здесь

В прошлом году в финал конкурса прошло три проекта из России: My Diggy Dog 2 от King Bird Games, Color Spots от UX Apps и Tricky Castle от Team Tricky – подать заявку можно до 1 июля.

ссылка на оригинал статьи https://habr.com/ru/company/google/blog/562346/

Почему Скотт пришёл к Южному Полюсу вторым, а Амундсен предпоследним

Если ты ненадёжен — то не стоит руководить полярной экспедицией.
Хотя если ты самонадеян до крайности — как ты сам догадаешься о своей некомпетентности?

История покорения Южного полюса — это готовый учебник менеджмента. Удачно получилось, что у нас есть пример двух руководителей, действующих в одной и той же ситуации, буквально сферический образец управления в вакууме. Вот вам одинаковая задача и условия, покажите, как делать надо и как не надо.

Суть дела: в январе 1911 в Антарктиде высадились две экспедиции: британская Роберта Скотта и норвежская Руаля Амундсена. Оба хотели достигнуть Южного полюса — последнего места на Земле, где ещё не побывал человек. Группы перезимовали у побережья и стартанули к полюсу почти одновременно. Кто успевал первым, тому и должна была достаться вся слава.


Каноничная карта маршрутов двух экспедиций

Шли параллельными маршрутами. У норвежцев путь от бухты до полюса был чуть короче, но они шли по неизведанному пути.
Англичане шли дорогой, которую уже разведал британец Эрнест Шеклтон в 1907 году. Тогда он не дошёл до полюса 180 км.

Однако Амундсен и его группа пришли на полюс раньше, потусили там трое суток и благополучно вернулись на базу. Скотт и четверо его компаньонов оказались у полюса на 34 дня позже норвежцев. И все погибли на обратном пути. У троих ещё были шансы выжить, но они замёрзли в палатке без еды и горючего, пока пережидали буран в течении 9 дней. До спасительного склада с продовольствием и керосином им оставалось пройти всего 18 километров.

Экспедиция Скотта была плохо спланирована и организована. Ответственность за это должен нести командир. Но всё искупила героическая гибель. Через 8 месяцев спасательная экспедиция с побережья нашла палатку с трупами. Нашли письма и дневник Скотта, фотоматериалы и даже геологические образцы, которые экспедиция не бросила до последнего.

В глазах мирового сообщества Скотт остался героем, достойнейшим представителем британской нации. А Амундсен — малоприятным типом, который чуть ли не украл у Скотта победу.


Руаль Амундсен, Хельмер Хансен, Сверре Хассель и Оскар Вистинг на Южном полюсе в декабре 1911 (Из архива Национальной библиотеки Норвегии)

Вот вам типичное сообщение британской газеты:
«Скотт пришёл к полюсу вторым. Амундсен — предпоследним!»

Если бы по горячим следам было проведено расследование и сделаны выводы — может это помогло бы британцам лучше планировать крупные операции, типа высадки в Галлиполи? Да ну, бред какой-то.

Давайте пройдёмся по некоторым аспектам экспедиции и оценим разный подход Скотта и Амундсена к планированию и управлению людьми.

1. Люди.
Кого вы возьмёте, чтобы идти 1300 км через ледяную пустыню и горы?
(а потом ещё столько же обратно).
Ну наверно подготовленных лыжников или опытных полярников?

В береговой партии Скотта было 65 человек: флотские офицеры, учёные, простые матросы. Группа для финального рывка к полюсу должна была состоять из четверых человек, включая самого Скотта:
Эдвард Уилсон — зоолог, врач и художник
Лоуренс Отс — кавалерист, внёс в фонд экспедиции 1000 фунтов за право пойти к полюсу
Эдгар Эванс — моряк.

Но уже в пути Скотт взял в группу пятого человека, хотя еда рассчитывалась на четверых. Пятым стал Генри Бауэрс — морской офицер. Лыж было четыре пары — Лоуренс Отс отдал свои лыжи Бауэрсу, а сам пошёл пешком.

У Амундсена в береговой партии было всего 9 человек. В группе для покорения полюса тоже было пятеро — все опытные лыжники и полярники. Имён приводить не буду, зачем их запоминать если они не погибли героями?

2. Транспорт
Как тащить припасы?
Скотт был опытный полярник, в 1901-1903 он уже руководил экспедицией в Антарктике. Всему учился на опыте, но не факт, что сделал верные выводы.
Скептически относился к: собакам и лыжам.
Допускал использование лошадей (маньчжурской породы).
Но основную ставку делал на пешую тягу.
План был такой: от побережья заброс снаряжения делают мотосани (3 штуки). Дальше караван из лошадей и собак. А на финальном рывке (700 км до полюса) — груз тянут люди.
Мотосани не помогли. Первые утонули при разгрузке с корабля. Двое других послужили недолго и скоро вышли из строя.

Выявилась проблема и с лошадьми — они плохо переносят холод, для ночёвки им нужно сооружать стену-укрытие. Плюс должны тащить себе фураж. Плюс не всякий снег им подходит — по дороге выяснилось, что они глубоко проваливаются копытами.

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

Амундсен сделал ставку на собак и лыжи.
На корабле с ним приплыли 52 гренландские лайки.
Собаки хорошо бегут в упряжках по любому снегу. Ночью они зарываются в снег и не мёрзнут. Питаются сушёной рыбой.
А главный лайфхак с собаками — в середине пути кого-то из них можно пристрелить, а их мясом накормить остальных.

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

Да, и лыжи. Пока собаки бежали в упряжках, люди бежали рядом на лыжах.

3. Еда
Рацион у обоих экспедиций был примерно одинаков, суточная доза составляла 4500 калорий:
пеммикан (сушёное мясо с жиром), сухое молоко, шоколад, галеты.
Амундсен использовал чуть больше свежего мяса — тюленей (добытых ранее на побережье) и собачатину.
Плюс Амундсен испытывал новинку: пеммикан с добавкой сушёных овощей и овсяных хлопьев (спонсором выступила норвежская армия). Норвежцы меньше страдали от недостатка витамина В12.
А за счёт того, что быстро сгоняли на полюс и обратно, не успели заболеть цингой.
Амундсен рассчитал еду с запасом, на обратном пути они даже сбрасывали лишнее продовольствие.


Ежедневный рацион участника экспедиции Скотта: какао, пеммикан, сахар, печенье, масло.

Однажды норвежцы встретили у своей палатки императорского пингвина. Убили его и съели (true story).

У Скотта в принципе было всё рассчитано с количеством еды (если не считать лишнего едока на финальном рывке к полюсу), но проблема оказалась с расходом калорий. Британцы тратили в среднем 5500 калорий — на тысячу калорий больше норвежцев, потому что тащили всё на себе. Теперь представьте, что это происходит каждый день. Люди слабели на глазах, организм восполнял недостаток калорий за счёт мышечной массы.

4. Промежуточные склады
Каждая экспедиция устроила склады с едой и горючим по своему маршруту.

Скотт делал просто: вот палатка с едой, поставьте сверху флаг.
Логично? Логично, только попробуй его найти на обратном пути. Если ваши следы замело, а на улице пурга.
А Амундсен отмечал каждый склад вереницей флажков:

В итоге англичанам приходилось тратить лишние силы, чтобы найти свои собственные припасы.

Самая трагедия произошла с ближайшим к базе складом Скотта под названием «Одна тонна». Когда перед стартом тащили провизию для него, все очень устали. Скотт пожалел людей и разрешил устроить склад не на 80-й параллели, как планировали, а в паре десятков километров дальше от полюса.
На обратном пути эти несколько километров стали критическими, люди погибли в шаге от спасения.

5. Испарившееся горючее. На обратном пути люди Скотта находили на складах бидоны с керосином наполовину пустыми — подвела оловянная пайка, которая трескалась на морозе. В результате керосин улетучивался.

У Амундсена с этим ситуация оказалась получше.
Исследователи в 1929 году нашли канистру норвежцев — керосин там ещё присутствовал.

6. Планирование впритык.
Амундсен при расчёте маршрута оставлял каждый четвёртый день на отдых. Чтобы группа могла просто остаться в палатках и целый день восстанавливаться.
Это пригодилось им при восхождении на ледник Акселя, когда попали в жуткую пургу и продвижение замедлилось. График в итоге не был нарушен, еды хватало.

Скотт не допускал в расчётах случайностей и задержек, не оставил никакого запаса по времени.
Он постоянно говорил: «Мы не можем позволить себе задержку». Готовя четырёхмесячное путешествие, он не заложил в свои планы возможность плохой погоды даже в течение четырёх дней. В худшем случае, как отметил Бауэрс в своём дневнике, «задержка будет означать всего лишь небольшую нехватку провизии на обратном пути, но это мелочи». Мелочи! Это при их дефиците калорий!

Итого: при одинаковых начальных условиях одна группа выполнила свою задачу и вернулась домой, вторая героически погибла. Подробности гибели британской экспедиции трогают душу.
Эдгар Эванс получил травму головы от падения и через сутки умер.
Лоуренс Отс, когда понял, что не может больше идти и не хочет задерживать остальных, сказал: «Я немного пройдусь и вернусь не скоро». Вышел из палатки без обуви и не вернулся.
Трое оставшихся шли столько, сколько позволяла погода. Зима наступила раньше обычного и оказалась гораздо суровее, чем можно было предполагать. Бауэрс и Уилсон умерли первыми, Скотт накрыл их одеялами, собрал дневники и письма, и умер сам.
Последней его записью было «ради Бога, позаботьтесь о наших близких».

Дневники и письма были опубликованы, в Британии объявили сбор пожертвований.
Денег хватило на оплату долгов экспедиции и на пенсию близким погибших.
Скотт стал национальным героем.
Автор «Питера Пена» писал: «Нет такого британца, который бы не почувствовал в эти дни прилив гордости, узнав из послания, написанного в палатке, на что способно его племя»

Поминальную службу провели в соборе Святого Павла, на церемонии присутствовали все высшие чины Великобритании во главе с королём.

А Амундсена в Британии приняли со скандалом: президент Королевского Географического Общества — Джордж Керзон произнёс двусмысленную речь. Амундсен описывал этот эпизод так:

«… Тщательно взвешивая слова, лорд Керзон обосновал приглашение меня в качестве докладчика, причём особо отметил то обстоятельство, что я приписываю часть нашего успеха собакам, после чего завершил свою речь словами: «Посему предлагаю всем присутствующим грянуть троекратное „ура“ в честь собак», — да ещё подчеркнул саркастический и унизительный смысл своего высказывания успокоительным жестом в мою сторону…»

Переосмысливать героический образ Роберта Скотта стали только во второй половине 20 века.
Британский журналист Роланд Хантфорд выпустил книгу «Скотт и Амундсен» — собственно её я сегодня пересказываю. Где в подробностях прошёлся по деталям экспедиций и показал разницу в подходах.
Скотт конечно герой, но при этом самоуверенный зазнайка, не умеющий признавать ошибок и извлекать уроки из собственного опыта.
Вы бы пошли с таким в экспедицию? А в бой?
А в мирное время, стали бы заниматься совместным проектом?

Не стоит думать, что героическое раздолбайство — это только британская черта. Буквально в следующем 1912 году пропало три русских арктических экспедиции — и там не всё в порядке было с организацией. Время перечитать «Двух капитанов» — кто всё-таки виноват в гибели экспедиции капитана Татаринова?

Берегите себя и выбирайте правильных руководителей.

Материалы по теме:

1. Собственно книга Хантфорда. У нас вышла под названием «Покорение южного полюса. Гонка лидеров». Годится как настольная книга для менеджеров проектов.

2. Мини-сериал 1985 года по книге. «Последнее место на Земле». В сериале засветились начинающие актёры Хью Грант и Билл Найи.

3. Инфографика двух экспедиций от Бюро Горбунова Ребята заморочились и вышло великолепно.

4. Статья на сайте birdinflight

5. Статья на Вархеде

Напоследок, цитата Амундсдена:

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

Автор: Юрий Деточкин


VDS серверы от Маклауд быстрые и безопасные.

Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!

ссылка на оригинал статьи https://habr.com/ru/company/macloud/blog/562514/