Обложка канала

Дизайнер учит код. Страница 6

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

  • Дизайнер учит код

    Интерактивный прототип Марти Лаурита на основе дизайна Ramotion.
  • Дизайнер учит код

    Немного статистики за 12 часов непрерывной работы бота (по состоянию на 04.05.2017, 00:04).

    Благодаря паре хороших репостов, моим ботом воспользовалось 269 человек. Суммарно, все посетители нажали на все кнопки 978 раз. Боту было передано 13,41 мб данных, а в ответ он отправил 12,65 мб. По внешней ссылке (портфолио) перешли 114 раз. 6 раз мне отправили сообщение с помощью бота.

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

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

    Хочу поблагодарить всех, кто уделил время и написал мне свой отзыв. Мне очень приятно! Спасибо!
  • Дизайнер учит код

    Количество пользователей и нажатий на кнопки за 12 часов.
  • Реклама

  • Дизайнер учит код

    Итог
    Многие из тех, кому я показывал бота — отнеслись к нему скептически. Мол, идея не нова, да и толку от него будет мало. Я готов поспорить.

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

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

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

    Я буду рад вашим отзывам и замечаниям по поводу работы бота. Можете писать мне лично (@boboshko), либо через бота (@BoboshkoRobot).

    Также буду рад, если вы запостите где-нибудь ссылку на бота: t.me/BoboshkoRobot.

    Пост получился таким большим, что пришлось разбивать на несколько! Спасибо, что дочитали!
  • Дизайнер учит код

    Привет! Хайпанём немножечко?

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

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

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

    Во-первых, хочу сказать спасибо @JuniorPomidor (Twitter) за помощь с освоением библиотек, примеры кода и терпение.

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

    Технологии
    Бот написан на JavaScript (ECMAscript 6) с использованием библиотек Telegraf и Telegraf Botanio.

    Telegraf — это framework для создания ботов на основе API Telegram, а Telegraf Botanio — это «обёртка» API AppMetrica, которая написана специально для Telegraf.

    Благодаря Telegraf Botanio, я знаю, сколько людей пользовалось ботом, как долго, на какие кнопки они нажимали и так далее.

    Весь код я храню в приватном репозитории на Bitbucket. Основной файл бота — core.js. Он хранит в себе практически весь код (привет, говнокод) и занимает всего 153 строки с учётом комментариев. Весь текст вынесен в text.json. Ключи тоже хранятся отдельно.

    Тут чуть подробнее. Оказалось, что есть переменные окружения, в которые можно записывать ключи, чтобы они не хранились в исполняемом коде (если я правильно понял суть работы) и не были скомпрометированы (если что). В идеале, именно так должно быть, но я пока так не умею.

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

    На стороне сервера, бот работает через pm2, который заодно записывает логи.

    Сервер
    Бот «живёт» на дешёвом VDS-хостинге за 150 ₽ в месяц.

    Параметры сервера: 1 ядро (CPU), 512 мб (RAM), 5 гб (SSD). Также на моём тарифе есть ограничения на входящий и исходящий трафик — 250 гб в месяц. Для бота более чем достаточно.

    Но есть и минусы. Так, например, у хостера нет подписанных SSL-сертификатов, что осложняет использование Webhook. Правда, можно самому поднять веб-сервер и сделать самоподписанный сертификат — что является оптимальным выходом из ситуации.

    Минусы
    Буду честен — есть и проблемы.

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

    Если что-то пошло не так, то бот будет возвращать случайную ошибку. Напишите команду /start, чтобы всё исправить. После этого бот должен перезапуститься. Либо удалите его из списка чатов и снова добавьте. Так тоже будет работать.

    Есть вероятность, что на Windows Phone нет клавиатуры. Но это не точно. Если вы используете Telegram на Windows Phone, напишите мне пожалуйста и расскажите, на месте у вас клавиатура или нет?
  • Дизайнер учит код

    Есть ли среди моих любимых подписчиков те, кто писал Telegram-ботов на Node.js? Можете ответить на пару простых вопросов? Пишите @boboshko.
  • Дизайнер учит код

    Функции. Часть 1

    Как мне объяснили взрослые ребята, функции — это краеугольный камень JavaScript. Функции нужны для того, чтобы «прятать» в них большой код и вызывать его в нужных местах. Также, функции позволяют многократно исполнять нужный код. Пример простой функции:

    var myFunction = function () {
    console.log("Пёсики и котики!");
    };
    myFunction();
    //result Пёсики и котики!


    myFunction(); — вызывает функцию и исполняет её тело.

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

    var cat = function (catName) {
    console.log("Мой любимый котик — " + catName + ".");
    }
    cat("Чехов");
    //result Мой любимый котик — Чехов.


    catName — имя аргумента. При исполнении кода имя изменится на Чехов.

    Функцию можно исполнять сколько угодно раз. Делается это с помощью цикла:

    var cats = function (howManyTimes) {
    for (var i = 0; i < howManyTimes; i++) {
    console.log("Котик " + i);
    }
    };
    cats(5);
    //result Посчитает котиков до 5


    cats(5); — количество итераций цикла.

    В функцию можно передавать больше одного аргумента:

    var doublePrint = function (howManyTimes, animal) {
    for (var i = 0; i < howManyTimes; i++) {
    console.log(" " + animal + i);
    }
    }
    doublePrint (5, "Котик ");
    //result Посчитает котиков до 5
  • Дизайнер учит код

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

    Репозиторий на GitHub, живой пример (обновляйте страницу, результат каждый раз разный) на сайте автора и материал по теме на русском.
  • Дизайнер учит код

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

    var testI = [];

    for (var i = 1; i < 100000000; i++) {
    testI.push(i);
    }

    var start1 = new Date().getTime();
    for (var j = 0; j < testI.length; j++) {
    200000000000000000000 * 3000000000000 + 30000000000000 + 100000000000000;
    }
    var end1 = new Date().getTime();
    console.log("Операция №1 заняла: " + (end1 - start1) + " мс.");

    var start2 = new Date().getTime();
    for (var q = 0, max = testI.length; q < max; q++) {
    20000000000000000000 * 3000000000000 + 30000000000000 + 100000000000000;
    }
    var end2 = new Date().getTime();
    console.log("Операция №2 заняла: " + (end2 - start2) + " мс.");
    //result Операция №1 заняла: 101 мс. Операция №2 заняла: 97 мс.


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

    Ещё раз спасибо за обратную связь! ❤️
  • Дизайнер учит код

    После поста про циклы, мне написал наш iOS-разработчик Миша. Миша сказал, что нет разницы, записывать длину массива в переменную или нет — производительность будет одинаковой. И предложил мне провести тест.

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

    Начнём. В этой части кода создаётся пустой массив и с помощью цикла for, в него складываются индексы:

    var testI = [];

    for (var i = 1; i < 100000000; i++) {
    testI.push(i);
    }


    Цикл, в котором длина массива считается при каждой итерации:

    var start1 = new Date().getTime();
    for (var j = 0; j < testI.lenght; j++) {
    200000000000000000000 * 3000000000000 + 30000000000000 + 100000000000000;
    }
    var end1 = new Date().getTime();
    console.log("Операция №1 заняла: " + (end1 - start1) + " мс.");


    Перед началом цикла в переменную start1 записывается начальное время, а после его выполнения в переменную end1 записывается конечное время. Затем, из конечного времени вычитается начальное и получается время выполнения цикла.

    Цикл, в котором длина массива записывается в переменную:

    var start2 = new Date().getTime();
    for (var q = 0, max = testI.lenght; q < max; q++) {
    20000000000000000000 * 3000000000000 + 30000000000000 + 100000000000000;
    }
    var end2 = new Date().getTime();
    console.log("Операция №2 заняла: " + (end2 - start2) + " мс.");


    Весь код целиком:

    var testI = [];

    for (var i = 1; i < 100000000; i++) {
    testI.push(i);
    }

    var start1 = new Date().getTime();
    for (var j = 0; j < testI.lenght; j++) {
    200000000000000000000 * 3000000000000 + 30000000000000 + 100000000000000;
    }
    var end1 = new Date().getTime();
    console.log("Операция №1 заняла: " + (end1 - start1) + " мс.");

    var start2 = new Date().getTime();
    for (var q = 0, max = testI.lenght; q < max; q++) {
    20000000000000000000 * 3000000000000 + 30000000000000 + 100000000000000;
    }
    var end2 = new Date().getTime();
    console.log("Операция №2 заняла: " + (end2 - start2) + " мс.");
    //result Операция №1 заняла: 0 мс. Операция №2 заняла: 0 мс.


    Результат
    Практически всегда, оба цикла выполняются меньше чем за 1 миллисекунду. Я пытался нагрузить систему, чтобы время расчётов увеличилось, но у меня ничего не вышло. Можете мне написать, если знаете, как это сделать.

    Вывод
    1. Тесты — дело неблагодарное.
    2. Можно особо не запариваться, если на производительность не влияет.
    3. Миша отчасти прав. Дело в том, что разница будет видна только в том случае, если расчёты будут более существенными. Но такого варианта я пока себе не могу представить.
  • Дизайнер учит код

    https://youtu.be/1G-C1YOoca8

    Я решил немного отвлечься от JavaScript и посмотреть видео с прошлогоднего Dribbble Meetup Russia, в котором Николай Березовский рассказывает про Flinto. Советую посмотреть хотя бы самое начало, где Коля рассказывает про виды инструментов для прототипирования.
  • Дизайнер учит код

    Пришла пора циклов! Циклы — это такая штука, которая повторяет код до тех пор, пока какое-либо условие даёт true.

    while — самый простой вид циклов. while используют, если есть какое-то определённое условие. Пример:

    var numbers = 0;
    while (numbers < 5) {
    console.log(numbers + "!");
    numbers++;
    }
    console.log("Расчёт окончен!");
    //result Посчитает от 0 до 4 и напишет «Расчёт окончен!»

    numbers++ — это приращение (увеличивает значение на 1). Если убрать эту строку, то цикл станет бесконечным, а результат всегда будет 0.

    for — чуть сложнее. Этот вид цикла чаще всего используют для работы с массивами. Пример предыдущего цикла, написанного через for:

    for (var numbers = 0; numbers < 5; numbers++) {
    console.log(numbers + "!");
    }
    console.log("Расчёт окончен!");
    //result Посчитает от 0 до 4 и напишет «Расчёт окончен!»

    Цикл for, который перебирает массив:

    var iLike = ["пёсика", "котика", "пожрать"];
    for (var i = 0; i < iLike.length; i++) {
    console.log("Я люблю " + iLike[i] + ".");
    }
    //result Я люблю пёсика. Я люблю котика. Я люблю пожрать.

    Мой товарищ Костя Вульсонов советует этот цикл переписать так:

    var iLike = ["пёсика", "котика", "пожрать"];
    for (var i = 0, max = iLike.length; i < max; i++) {
    console.log("Я люблю " + iLike[i] + ".");
    }
    //result Я люблю пёсика. Я люблю котика. Я люблю пожрать.

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

    Это далеко не все виды циклов. Я разобрал только самые простые. По мере необходимости буду узнавать новые.
  • Дизайнер учит код

    Прошу прощения! Метод Math.max — выводит самое большое число, а метод apply — позволяет запустить Math.max с массивом аргументов. Боги JavaScript! Не гневитесь!
  • Дизайнер учит код

    Только не путайте Александру Морган и Сашу! Это разные люди! 😁
  • Дизайнер учит код

    #ЗадачиОтСаши

    С опозданием, но всё-таки публикую вариант решения от Александры Морган:

    console.log(Math.max.apply(null, [1, 2, 3, 4, -5, 10, -100, 50, 99]));

    Стоит отметить, что Александра решила задач по своему. Если упрощать условия, то получается, что нужно вывести самое большое число. Собственно, метод Math.max.apply — выводит самое большое число из массива. В общем, очередная задачка на логику.

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

  • Дизайнер учит код

    #ЗадачиОтСаши

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

    var n1 = 9999;
    var n2 = 9998;

    if (n1 > n2) {
    console.log("Число " + n1 + " больше, чем " + n2 + "!");
    } else if (n1 < n2) {
    console.log("Число " + n2 + " больше, чем " + n1 + "!");
    } else {
    console.log("Оба числа равны!");
    }


    Как и в прошлый раз, вы можете прислать мне своё решение до 12:00 следующего дня.
  • Дизайнер учит код

    Второй день с товарищем работаем над собственным проектом. В общем, он за 10 минут в Principle собрал то, на что я во Framer потратил больше часа и не смог доделать из-за отсутсвия нужных знаний. Ещё раз убедился в том, что порог входа для работы с Framer — очень большой. Пойду поплачу.
  • Дизайнер учит код

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

    Условия (условные конструкции) — это такая штука, которая позволяет создавать условия, как ни странно. 😄 Пример: если на улице -30°, то купаться нельзя.

    У условий в JavaScript есть два вида конструкций: if и if...else. if — это true, а else — это false. Пример простого условия с использованием if:

    var lastName = "Бобошко";
    console.log("Привет, " + lastName + "!");
    if (lastName.length > 10) {
    console.log("У тебя длинная фамилия! Тяжело запомнить!");
    }
    //result Привет, Бобошко!


    if (lastName.length > 10) — это условие, а console.log("У тебя длинная фамилия! Тяжело запомнить!") — тело условия.

    Тот же самый пример, только с использованием if...else:

    var lastName = "Бобошко";
    console.log("Привет, " + lastName + "!");
    if (lastName.length > 10) {
    console.log("У тебя длинная фамилия! Тяжело запомнить!");
    } else {
    console.log("Фамилия у тебя не очень-то длинная!");
    }
    //result
    Привет, Бобошко!
    Фамилия у тебя не очень-то длинная!


    Этот код помогает мне определиться с тем, кого взять с собой на прогулку:

    var cat = false;
    var dog = true;

    if (cat) {
    console.log("Круто! Беру с собой на прогулку котика");
    } else if (dog) {
    console.log("Ладно! Пёсик на прогулке — тоже неплохо!");
    } else {
    console.log("Пусть идут они оба к чёрту! Я пойду один гулять!");
    }
    //result Ладно! Пёсик на прогулке — тоже неплохо!


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

    Наконец-то пошла жара! 🔥