Простейшая игра на Ardruino с дисплеем 1602 — Часть #1

Вот что у нас должно получиться, ну он еще умеет прыгать, ходить и бить злые кактусы, которые на него нападают, но к этому придем поэтапно 🙂

ЧАСТЬ #1 основы

Я заказал себе arduino, «так себе игрушка» подумал я, комплект маленький (для пробы) о чем в последствии пожалел. Хотелось раскрыть потенциал, но из-за отсутствия дополнительных модулей этого не выходило, пришлось экспериментировать, подрубал ardruino к системе безопасности и смотрел как датчики делают свою работу, потом решил сделать звуковую сигнализацию (используя пративную пищалку из комплекта), так сказать отучивал собак громко или неожиданно лаять 🙂 и тут мои руки дошли до дисплея 1602. «Хм… это же настоящий дисплей» подумал я, но тут же разочаровался узнав что он сжирает почти половину всех контактов на самой ardruino. Покопавшись я нашел странную плату в комплекте «i2C» и очень подозрительно было ТО! Что количество дырдочек совпало с количеством пимпочек на дисплее. «Хм, не с проста…» подумал я, и решил их спаять. Чуть позже я понял что сделал верную штуку и теперь мой дисплей съедает всего два канала. Начал изучать, что же это за дисплей и что он умеет. Изучив достаточное количество материала я узнал, что дисплей чисто текстовый, но о чудо! Он может обработать 8 новых символов, габаритами 5х8 пикселей. Ну что же, давайте начнем писать игру! Первое, это надо придумать что за игра будет, решил сделать подобие динозаврика гуугл хром, но с парочкой фишек так сказать, для начала я думаю сойдет 🙂 но ведь надо еще чем-то управлять, причем многокнопочным, долго думать не пришлось. Взял ИК пульт из комплекта.

image

«Вот и джойстик» подозрительно пробормотал я себе под нос, думая о задержке от пульта, четкости работы ИК датчика да и вообще об адекватности данной идеи, но делать было нечего, я мог бы обучить ardruino работать с клавиатурой для компа, но было действительно лень это делать. Так что приступил я записывать коды пульта, что бы в дальнейшем с ними работать. Код для микроконтролера тут простейший:

"--------------------------------------------------------------------------" // качаем библиотеку IRremote #include IRrecv irrecv (A0) // включаем аналоговый порт для датчика Void setup () {      Serial.begin(9600); // настраиваем скорость com порта      Irrecv.enableIRIn(); // запускаем сам сенсор } Void loop () {      If (irrecv.decode( &result )) // если датчик видит любой ИК сигнал, то условие выполнено      {           Serial.printIn (result.value, HEX); //считываем код с пульта и выводим его в логи порта      } } "--------------------------------------------------------------------------"

После заливки сего в ardruino и подключив его как надо, мы можем начать записывать с лога порта цифорки, после нажатия на кнопки ИК устройства. Но тут как раз я хочу вам уточнить про то, как надо подключать датчик ИК.

Если мы смотрим на датчик, мы видим три ножки, левая (аналоговый сигнал), средняя (масса), правая (плюс 5V).

image

Так как я еще мало представлял как это будет вообще работать, я начал эксперименты. Сначала делал код скетча шаговый, через (delay(time)) сначала я не подозревал что это плохая идея 🙂
В чем главный косяк. Данный микроконтроллер не умеет делать мультизадачность. Он считает код сверху вниз, проходя по всем веткам и функциям и после завершения, он начинает заново. И вот, когда у нас этих «delay» в коде становиться очень много, мы начинаем замечать явные задержки. Кстати да, зачем нам много «delay» вообще нужно. Когда мы делаем игру, у нас начинает расти количество проверок и взаимодействий. Например к нам движется враг а я хочу его перепрыгнуть, я нажимаю «прыжок» а по плану, я должен зависнуть в воздухе к примеру на 0.8f секунд в воздухе, вот и вся игра и зависает на эти 0.8f секунды. «Косяк» подумал я и начал думать над решением. Решение было найдено быстро. Сам микроконтроллер умеет достаточно быстро читать код от начала до конца, (если ему не мешать) и еще он умеет считать время с начала его включения. Вот это то нам и надо. Теперь мы всего лишь создаем переменные которые будут хранить время на то или иное действие и переменную которая сверяет разницу от того сколько сейчас время и во сколько надо активировать код. Ardruino за секунду, берет 1000 миллисекунд, достаточно удобно. Вот фрагмент когда что бы стало понятнее:

"--------------------------------------------------------------------------" // данный пример фрагмента кода, очищает экран, грубо говоря это наша частота обновления кадров // переменные long ClearTime = 150; // 150 = 0.15f секунды или ~6 кадров в секунду long ClearTimeCheck = 0; // проверка, будет меняться в процессе работы кода long currentMillis = 0; // переменная таймера  void loop () {      currentMillis = millis(); // переменная таймера = время в миллисекундах } void clearscreen () //функция обновления экрана { //      if (currentMillis - ClearTimeCheck >= ClearTime) // если (время работы - проверка больше или равно 0.15f то условие выполнено      {           ClearTimeCheck = currentMillis; // выравниваем проверку для обнуления нашего счетчика          lcd.clear(); // выполняем само действие, а именно очистку экрана      } } "--------------------------------------------------------------------------"

Не трудно, правда?

После переписывания всего кода на новый лад, игра стала работать быстрео и четко, симулировать мультизадачные действия 🙂 Я что-то далеко зашел. Ведь нам надо еще сделать персонажа, подобие интерфейса и анимации. Так как мы можем создавать всего восемь новых символов, нам надо как-то это все промутить по умному. На дисплее много объектов делать я пока что не планирую, следовательно, можно сделать так что бы у меня было как раз восемь активных объектов на экране за одну обработку кода. Что же это будет? Ну естественно главный герой, удар, злодей, сердечко и индикатор здоровья. Для начала этого с головой хватит. Да и у меня еще три уникальных объекта в запасе.

Главный герой будет у нас выглядеть так:

Процесс вписывания нового символа, я произвожу двоичным кодом (мне так удобно)
выглядеть он будет так:

01110
01110
00100
01110
10101
00100
01110
01010

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

Теперь к нашему коду, добавиться еще один набор двоичных цифорок, а именно такой:

00000
01110
01110
00100
11111
00100
01110
01010

Как сделать анимацию на этом дисплее, логику я указал выше, а теперь перейдем к практике, в данный момент, расположим его на центр экрана, и заставим просто стоять на месте, и помните, наша задача использовать только одну ячейку памяти на два спрайта анимации. Это легче чем кажется:

"--------------------------------------------------------------------------" #include <Wire.h>  #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F,16,2);  // Устанавливаем дисплей  long AnimatedTime = 300; // скорость анимации главного герое long AnimatedTimeCheck = 0; // проверка скорости (как и в прошлом примере) int AnimPlayer = 1; // проверка состояния анимации  int GGpozX = 8; // положение горизонталь int GGpozY = 1; // положение вертикаль 1 это 2я строка а 0 это первая строка long currentMillis = 0; // переменная таймера  //Создаем переменные наших объектов, их может быть сколько угодно, они же переменные :) enum { SYMBOL_HEIGHT = 8 }; byte Player_1[SYMBOL_HEIGHT] = {B01110,B01110,B00100,B01110,B10101,B00100,B01110,B01010,}; // спрайт 1 byte Player_2[SYMBOL_HEIGHT] = {B00000,B01110,B01110,B00100,B11111,B00100,B01110,B01010,}; // спрайт 2  void setup()  {   lcd.init();                        lcd.backlight();// Включаем подсветку дисплея   loop();   PlAn(); }  void loop()  {      if (AnimPlayer != 50)      { // это проверка смерти персонажа, пока что не забивайте себе голову :)      // --------------------------- Animated ->      // -------------------- Player ->      if (AnimPlayer == 1){lcd.createChar(0, Player_1);} //если состояние 1 то спрайт 1      //(lcd.createChar(номер ячейки памяти от 0 до 7, название переменной спрайта))      if (AnimPlayer == 2){lcd.createChar(0, Player_2);} //если состояние 2 то спрайт 2      }      // --------------------------- <- Animated      currentMillis = millis(); // переменная таймера = время в миллисекундах      PlAn(); } void PlAn () {      if (AnimPlayer == 1) // если состояние 1 то      {           lcd.setCursor(GGpozX, GGpozY); // ставим "курсор" на точку координат нашего героя           lcd.write(0); // рисуем спрайт из ячейки памяти на то место где "курсор"      }      if (AnimPlayer == 2) // аналогично №1      {           lcd.setCursor(GGpozX, GGpozY);           lcd.write(0);      }      if (currentMillis - AnimatedTimeCheck >= AnimatedTime) // проверка времени как и до этого      {           AnimatedTimeCheck = currentMillis; // ну тут уже понятно           if (AnimPlayer == 2){AnimPlayer = 1; return;} //если положение 2 то делаем 1 и стопорим этот фрагмент кода           if (AnimPlayer == 1){AnimPlayer = 2;} //если 1 то 2 и стопорить нет смысла так что не забиваем память лишним кодом, ее у нас там и так очень мало      } } "--------------------------------------------------------------------------"

После запуска, мы видим чУловечка, который находиться в центре экрана, на 2й строке и качается, так сказать.

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

Остальное скоро 🙂 писать еще очень много чего, так что гляну как это вообще будет вам интересно и если да, то завтра же приступлю к написанию продолжения.

Всем спасибо за внимание, чао-какао!


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

CloudFlare реализовала поддержку Encrypted SNI

24 сентября CloudFlare объявили о поддержке расширения TLS 1.3 Encrypted SNI
blog.cloudflare.com/encrypted-sni

image

Преимущества ESNI

  • Никто не видит на какой домен вы заходите. Все что знает провайдер это только IP адрес на который вы обращаетесь.
  • Domain Fronting не нужен.

Как ESNI работает
В современном интернете на одном IP адресе может располагаться множество различных доменов. Чтобы предоставить вам верный сертификат серверу необходимо знать на какой именно домен вы обращаетесь. Поэтому hostname передается открытым текстом, до начала установления TLS сессии.

Схема работы SNI
image

ESNI шифрует и эту часть общения клиента с сервером. Клиент берет публичный ключ сервера из DNS и шифрует им все данные до установления TLS сессии.

Схема работы ESNI
image

Ложка дегтя
ENSI сильно зависим от DNS. Настолько сильно что при текущей реализации DNS (plain text) поставить DPI на DNS протокол и блокировать все поля с публичными ключами серверов элементарно. Эта проблема исправима только массовым переходом на DNSSEC или DNS over HTTPS. Судя по блогу разработчиков Хрома этот переход уже на горами.
ESNI должен поддерживаться браузерами. Пока с поддержкой не очень.

Что мы от этого получим?
Цензура в интернете сильно усложнится. Сейчас большинство блокировок происходит по DNS именам. Все эти блокировки перестанут работать. Останутся только блокировки DNS запросов или IP адресов.
Блокировки DNS запросов перестанут работать после включения по умолчанию DNS over HTTPS в стандартных браузерах. И останется только одна возможность блокировать по IP адресам. Можно блокировать или DNS сервера или неугодные сайты.
Блокировки по IP адресам это для очень смелых людей. Одной блокировкой может зацепить множество непричастных доменов и нет адекватного способа проверить заранее кого именно зацепит. А блокируемый сервис может в пару кликов, да и вообще автоматически, сменить адрес на не заблокированный. Его пользователи даже ничего не заметят.

Итого
Жизнь станет чуть-чуть лучше. Но не сейчас. До полноценной поддержки ESNI еще необходимо сделать несколько шагов.

Ссылки
Проверить свой браузер на поддержку TLS 1.3, ESNI и шифрование DNS можно тут: www.cloudflare.com/ssl/encrypted-sni


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

Фотоэкскурсия по офису «Аудиомании»: часть вторая

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

Адрес магазина — Барабанный переулок, дом 4. Он находится в пяти минутах ходьбы от стации м. Электрозаводская. Рядом со входом на территорию бизнес-центра висит вывеска «Аудиомания» со стрелкой, которая указывает на проходную. Чтобы попасть к нам, вам нужно найти вход №11. Для этого пройдите КПП прямо, а затем сверните налево. У 11-го входа будет еще одна наша вывеска.

Торговый зал, служебные помещения (например, инженерная комната) и склад находятся рядом с большим шоурумом (на фото ниже), о котором мы рассказывали в первой части фотоэкскурсии.

Инженерная комната

Как и в прошлый раз мы не стали специально готовить помещения к фотосъемке. Показываем творческий беспорядок таким, какой он есть — в процессе работы наших специалистов.

Здесь инженеры собирают акустические системы, проектируют и тестируют аппаратуру. Поэтому в этом помещении (как и в большом шоуруме) стены проложены специальным демпфирующим материалом и звукопоглощающим покрытием. Здесь созданы все условия для работы с акустикой.

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

Офис

В магазине на «На Барабанном» работают наши консультанты и специалисты по Hi-Fi и High End оборудованию. Кстати, половина наших коллег работает в Аудиомании более трех лет.

Их опыт позволяет нам постоянно повышать планку качества и завоевывать награды. Например, мы получили звание самой клиентоориентированной компании Рунета в рамках E-commerce Staff Party. Также мы выиграли две премии Online Retail Awards.

Чтобы продавцы могли решить задачи клиентов и ответить на их вопросы, мы проводим дополнительное обучение в рамках нескольких месяцев. После стажировки продавец становится консультантом и, позже, специалистом (по конкретному типу оборудования).

Часть сотрудников работает в торговом зале. Но есть группа людей, которая отвечает на телефонные звонки и в онлайн-чате. Если в магазин поступает звонок, а все менеджеры оказываются заняты, он перенаправляется в наш магазин в Петербурге. Если и там наблюдается полный загруз, то трубку берет отдел маркетинга. Была ситуация, когда так по цепочке звонок дошел до генерального директора, и он лично завершил продажу.

У продавцов нет каких-либо скриптов, а время разговора с клиентом не ограничено. Потому беседы по несколько часов — это нормальная ситуация, главное — решить вопрос клиента. Такой подход к работе помогает нам развиваться на рынке.

«Аудиомания» работает с 1997 года, и за это время у нас накопилось большое количество дипломов. Есть награды «Лучший интернет-магазин Hi-Fi» и «Открытие года 2016» от дистрибьютора профессионального звукового оборудование MixArt. Мы побеждали в номинациях «Hi-Fi. Лучший интернет-магазин» и «Лучший салон 2010 года» и многих других.

Торговый зал

В торговом зале справа от входа за стойкой сидят продавцы. За их спинами расположился стенд с наушниками. Ценовые категории самые разные: от бюджетных Fischer Audio до премиальных Beyerdynamic. Любую модель можно пощупать и прослушать прямо на месте. Для проигрывания музыки можно использовать свои устройства и любимые композиции.

Такой подход мы всячески приветствуем.

На постаменте в середине зала расположились несколько акустических систем. В центре стоит колонка бренда Old School, выполненная в духе 80-х годов. Здесь также установлены стойки с виниловыми пластинками. Каждый может прийти и подобрать композиции на свой вкус. При этом заказ можно оформить онлайн — у нас на сайте есть каталог с виниловой продукцией.

В стеклянных витринах стоят коллекционные виниловые издания.

Есть бокс-сет группы «Кино» из восьми пластинок, композиции Джими Хендрикса, а также альбомы Боба Марли в металлическом кейсе ручной работы.

За стойками с виниловыми пластинками у нас расположилась еще одна небольшая офисная секция. В ней — пара рабочих мест для сотрудников.

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

Помимо этого для DIY у нас есть динамики и электронные компоненты (конденсаторы, резисторы, трансформаторы и лампы), разного рода разъёмы, винты, другой крепеж и компоненты для АС.

Напротив компактной офисной части расположился вход в малый шоурум.

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

Склад

На наших складах есть большая часть товара, представленного в электронном каталоге. Потому очень часто клиенты могут получить свою покупку прямо в день заказа. На фото — не совсем склад. Здесь стоят колонки, которые не поместились в малом шоуруме. Их туда выносят по необходимости.

Чтобы повысить эффективность работы сотрудников склада, мы разработали несколько методик. Например, сейчас на складе «Аудиомании» можно встретить три типа «емкостей» для хранения товара: ящики для мелочи (конденсаторов, резисторов, радиоламп), лотки для более крупных элементов (динамиков, рупоров и др.) и полки на стеллажах (там стоит аппаратура).

Каждая полка и каждый ящичек имеют свой штрихкод, с помощью которого сотрудники могут быстро найти нужный товар. Мы не наклеиваем этикетки на небольшие радиоэлементы, потому что они всегда лежат в нужной ячейке. Ни одно известное нам готовое решение по управлению складом не умеет работать с товарами без индивидуальной этикетки. Считываются штрихкоды с помощью смартфона и Bluetooth-сканера — для этого мы написали собственный софт.

Сборка заказа происходит следующим образом. Сперва сотрудник сканирует штрихкод с экрана монитора и получает новую задачу на смартфон. Система отражает номер места и наименование вещи, которую нужно забрать. Работник идет туда, поочередно сканируя штрихкоды полки (ячейки) и товара. Так он уверен, что пакует в коробку нужный покупателю товар.

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

На этом все, благодарим за внимание и ждем вас в гости!


Больше интересного о звуке, музыке, акустике и аудиогаджетах — в нашем Telegram-канале:

Необычные аудиогаджеты
Гид по встраиваемой акустике
Необычная портативка
Музыка для растений
Кино на пластинках
Что такое HD-винил
Песни воды



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

Финансовая независимость, мой путь

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

Прежде всего для того чтобы избежать «ошибки выжившего» хочу оговорить пару моментов:

  1. Мне нравится такой стиль жизни
  2. В моей жизни несомненно есть элемент везения
  3. Мой путь ещё не закончен, надо ещё лет 10-15.

Так что же это за волшебный термин такой? — Финансовая независимость.
Для меня это возможность бросить работу в любой момент и обеспечивать привычный образ жизни семьи на срок не менее 5 лет. В самом простом режиме без форс мажорных обстоятельств для моей семьи это возможно уже сейчас, но для этого необходимо реализовать сценарий переезда в маленький город где есть резервная недвижимость приносящая сейчас скромный доход. При этом пассивные накопления перестанут реинвестироваться и будут использоваться для жизни, квартира в городе миллионнике будет сдаваться. Уровень дохода будет примерно 5 прожиточных минимумов на семью из 4-х человек (два взрослых, два ребенка). На шикарную жизнь конечно не хватит, но наличие своего огорода позволит существенно смягчить ситуацию.

Теперь о том как же живет моя семья, и какие основы заложены в распределение и использование бюджета.

Структура расходов

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

Большую часть расходов как видно из диаграммы и расшифровки к ней, составляют путешествия. Однако это не совсем корректно (исправлять не стал), на самом деле здесь сидят расходы на путешествия в зарубежные языковые школы со старшим сыном. Вообще обучение для нас это приоритет, это нематериальный актив который навсегда с нами. Обучение на постоянной основе большей частью бесплатное — это государственные спортивные секции и дом пионеров (английский, робототехника оба сына), есть платные кружки у детей в садике и школе. В обучении так же заложены затраты на наше с женой развитие.
Как видно затраты на жилье сопоставимы с питанием, это связанно с оплатой ЖКХ на несколько объектов недвижимости(наших и обоих родителей).
Несомненный приоритет это здоровье, больше всего здесь стоматологии, особенно детской. Здесь как показал личный опыт лучше сейчас и дорого, чем потом и не за какие деньги. Достаточно много в бюджете съедает авто, можно было бы от него отказаться, но он позволяет стабильно навещать родителей, и исполняет ещё очень важную функцию, о ней в разделе питание.

Питание

Много споров, про здоровое питание и его стоимость. Для нас здоровое питание, приготовленное самостоятельно. Когда ты готовишь сам из первичных продуктов, можешь быть более менее уверен в качестве. Продукты по акциям никогда не покупаем, для этого есть крупно оптовые базы, куда можно съездить на автомобиле раз месяц и купить все необходимые базовые продукты.
От многих знакомых на отличает отсутствие трат, и это очень большой размер на: алкоголь, сигареты, сахар и сладкое. Из сладкого дети едят мед, сахар только при готовке. Обедам только дома, так как до работы 1 км и можно ходить (как раз позволяет выполнять ежедневный норматив 10 км). Жилье рядом с работой, это не случайность а целенаправленный выбор. Мы много раз переезжали и всегда ищем жилье рядом с работой, лучше переплатить на старте, чем мучится потом. Вообще жить рядом с работой это экономия самого ценного ресурса времени.

Вещи

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

Доходы

Кроме основного источника дохода — работы, есть возможность получить ещё денежные средства.
Пассивные инвестиции разделены на ИИС, акции и депозиты. Стабильно и просто, на данный средняя доходность с данных инвестиций 7%. Тут ничего придумывать не надо, всё уже придумано за нас. ИИС и акции это в длинный период, депозит на короткие, так как ест возможность всё время пополнять. Здесь же главное правило, все избытки, но не менее 30% класть на депозит два раза в месяц.
Дополнительно деньги не зарабатываются, а возвращаются, через акции банков (кэшбэк), наличие карт РЖД Бонус, Аэрофлот бонус, S7. Кстати мили часто можно потратить не только на полеты, но и на товары. И в банках всегда вступайте по возможности в привелегированные программы обслуживания там часто есть критерии бесплатности пользования, а благодаря участию получаешь дополнительные бонусы, в частности — у меня повышенная ставка по вкладу, priority pass, бесплатная страховка путешественника на всю семью.
Следующее важное действие которое необходимо делать раз в год — возврат средств по подоходному налогу, тут список очень обширен:

Варианты за что можно вернуть

-Покупка квартиры
-Отделка квартиры
-Покупка комнаты (доли квартиры)
-Покупка или строительство дома
-Покупка земельного участка
-Проценты по ипотеке (целевому займу)
-Обучение собственное и детей
-Расходы на лечение и лекарства
-Расходы на добровольное медицинское страхование (ДМС)
-Расходы на добровольное пенсионное обеспечение
-Платежи в негосударственные пенсионные фонды

  • Возвраты за детей

Заполнять декларации можно в личном кабинете налогоплательщика, не разу не посещая налоговую, но если уж совсем лень 400 руб и вам всё заполнят.
Всё не нужное, что не подымается рука выбросить, или подымается, сразу идет на АВИ… О и ему подобные сайты. Цену обычно ставим какую хотим, потом постепенно снижаем. Продавалось всё от не нужных проводов питания для компьютера до старого фильмоскопа. Здесь принцип даже 100 руб гораздо больше чем ничего, плюс тешит мысль что меньше загрязняешь природу мусором.
Важный момент, кредиты — зло. Не можешь накопить, значить вещь не нужна, можешь накопить — копи. Положите на сберегательный счет по 6% и копите ещё эффективнее. Использовать выгодно ипотеку, там можно вернуть как уже описано выше 13%.

Риски

Главный риск несомненно страновой, но 90-е пережили, а сейчас гораздо лучше. Кто боится за рубли или не доверяет российским биржевым эмитентам, сейчас в режиме онлайн можно купить акции хоть Apple, хоть Xiaomi.

Заключение

Работать до пенсии в принципе планирую, может и дальше, главное в свое удовольствие. Мне вообще пока всё нравится, просто пассивные доходы делают нас более уверенными и независимыми, и тут конечно мне импонирует идея БОД. К пенсионным накоплениям отношусь как к лотерее, может и выгорит но наедятся только на неё не наш метод.
Вообщем и в России можно выйти на пенсию заслуженный отдых пораньше, если относится к жизни проще.


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

История одного вью-контроллера, который хотел показываться красиво

Жил был скромный вью-контроллер VCYellow. И не было у него ни картинки, ни текста, ни даже малюсенькой бизнес логики. Жил он обычной вью-контроллерской жизнью.

Его товарищ вью-контроллер VCMain иногда презентовал его миру:

class VCMain: UIViewController { ... @IBAction func onBtnTapMeTapped(_ sender: Any) {     let vcYellow = self.storyboard!.instantiateViewController(withIdentifier: "VCYellow") as! VCYellow     self.present(vcYellow, animated: true, completion: nil) }

А VCYellow в свою очередь скрывался при помощи единственной кнопки "X", которой он, кстати говоря, очень гордился:

class VCYellow: UIViewController { ... @IBAction func onBtnCloseTapped(_ sender: Any) {     self.dismiss(animated: true, completion: nil) }

И выглядело это не то чтобы плохо, но скучно и обыденно:

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

Шли года… и так и осталась бы мечта мечтой, если бы не узнал VCYellow о магии под названием:

UIViewControllerTransitioningDelegate

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

extension VCYellow: UIViewControllerTransitioningDelegate {     func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {         return AnimatorPresent(startFrame: self.startFrame)     }      func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {         return AnimatorDismiss(endFrame: self.startFrame)     } }

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

А потом и сам морально настроился. Потому как без правильного настроя, как известно, никакая магия не работает:

override func viewDidLoad() {     super.viewDidLoad()     self.modalPresentationStyle = .custom     self.transitioningDelegate = self }

Попросил он своего друга VCMain презентануть себя, чтобы проверить как магия сработает и… сработала она никак…
Оказалось, что AnimatorPresent и AnimatorDismiss сами собой не появляются.

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

Во-первых надо задать время, отведённое для анимации:

func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {     return 0.3 }

а во-вторых обозначить саму анимацию:

 func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {     //1     guard let vcTo = transitionContext.viewController(forKey: .to),         let snapshot = vcTo.view.snapshotView(afterScreenUpdates: true) else {         return     }      //2     let vContainer = transitionContext.containerView      //3     vcTo.view.isHidden = true     vContainer.addSubview(vcTo.view)      //4     snapshot.frame = self.startFrame     vContainer.addSubview(snapshot)      UIView.animate(withDuration: 0.3, animations: {         //5         snapshot.frame = (transitionContext.finalFrame(for: vcTo))     }, completion: { success in         //6         vcTo.view.isHidden = false         snapshot.removeFromSuperview()         transitionContext.completeTransition(true)     }) } 

  1. Вытащить презентуемый вью-контроллер(в нашем случае VCYellow) и сфоткать его. Фотка нужна для упрощения анимации.
  2. Получить вьюшку, на которой будет происходить анимационное колдунство. Назовем её контекст.
  3. Нацепить вьюху конечного контроллера на контекст и скрыть её. Показать
  4. её было решено после того как закончится анимация.
  5. Подготовить фотку для анимации. Уменьшить до начальных размеров и кинуть на контекст.
  6. Расщеперить фотку на весь экран, тем самым анимировав процесс презентации.
  7. После окончания анимации показать настоящую вьюху конечного контроллера,
  8. избавиться от фотки и сообщить, что действо окончено.

В результате вышел вот такой аниматор для показа:

import UIKit  class AnimatorPresent: NSObject, UIViewControllerAnimatedTransitioning {     let startFrame: CGRect      init(startFrame: CGRect) {         self.startFrame = startFrame     }      func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {         return 0.3     }      func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {         guard let vcTo = transitionContext.viewController(forKey: .to),         let snapshot = vcTo.view.snapshotView(afterScreenUpdates: true) else {             return         }          let vContainer = transitionContext.containerView          vcTo.view.isHidden = true         vContainer.addSubview(vcTo.view)          snapshot.frame = self.startFrame         vContainer.addSubview(snapshot)          UIView.animate(withDuration: 0.3, animations: {             snapshot.frame = (transitionContext.finalFrame(for: vcTo))         }, completion: { success in             vcTo.view.isHidden = false             snapshot.removeFromSuperview()             transitionContext.completeTransition(true)         })     } }

А после этого несложно было написать аниматор для скрывания, который делает примерно то же самое, но наоборот:

import UIKit  class AnimatorDismiss: NSObject, UIViewControllerAnimatedTransitioning {      let endFrame: CGRect      init(endFrame: CGRect) {         self.endFrame = endFrame     }      func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {         return 0.3     }      func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {         guard let vcTo = transitionContext.viewController(forKey: .to),         let vcFrom = transitionContext.viewController(forKey: .from),         let snapshot = vcFrom.view.snapshotView(afterScreenUpdates: true) else {             return         }          let vContainer = transitionContext.containerView         vContainer.addSubview(vcTo.view)         vContainer.addSubview(snapshot)          vcFrom.view.isHidden = true          UIView.animate(withDuration: 0.3, animations: {             snapshot.frame = self.endFrame         }, completion: { success in             transitionContext.completeTransition(true)         })     } }

Закончив все доделки, VCYellow опять попросил своего друга VCMain презентовать себя и о чудо!

Магия сработала! Мечта VCYellow сбылась! Теперь он может показываться и скрываться как ему захочется и ничто не будет ограничивать его фантазию!

Проект-пример можно скачать тут

Статья, которую я использовал для вдохновения находится тут


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