среда, 4 июля 2018 г.

Javascript: да тут все просто, надо только помнить...

...

  • как правильно объявить переменную и задать ей значение: 'a = 1;'  или 'var a = 1;' или 'let a = 1;'  или 'const a = 1;' или 'this.a = 1;'  или 'self.a = 1;'  или 'this.['a'] = 1;'  или 'that.a= 1;' или 'лучше использовать параметр через замыкание вместо новой переменной'
  • new Date(1, 31, 2016) - это "02 марта 2016"
  • new Date("31.01.2016") - это "30 января 2016 22:00 UTC+3", а new Date("01.31.2016") - это "31 января 2016 00:00 UTC+3"
  • Date.getMonth(), но Date.getFullYear(), а не Date.getYear()
  • Date.setMonth, Date.setHours, но почему-то Date.setDate для 'day of the month'
  • '===' и '==' - это два разных алгоритма сравнения
  • NaN === NaN - это false
  • NaN === NaN , isNaN и Number.isNaN - это разные алгоритмы
  • Array.push/pop/slice, а classList.add/remove
  • ParentNode.children, но ParentNode.childElementCount и даже ParentNode.firstElementChild
  • ParentNode.children - это не то же самое что ParentNode.childNodes
  • ParentNode.childNodes - это live NodeList, а document.querySelectorAll - тоже NodeList, только static (not live)
  • (0.1 + 0.2) === 0.3 - нет, они не равны, это две разные цифры и результатом сравнения будет "false"
  • как правильно вызвать метод: 'run();' или 'this.run();' или '_self.run();' или 'run.apply(myObj);' или 'run.call(myObj);' или 'run.call(myObj, arguments);' или 'run.apply(myObj, arguments);' или 'run.call(myObj, start, end);' или 'run.call(myObj, arguments);' 
  • как правильно объявить метод: 'function run(a) {}' или 'this.run = function (a) {};' или 'this.run = (a) => {};' или 'this.run = run.bind(this);' или 'return { run = run.bind(self) };' или 'class { function run(a) {}}' или 'class { run(a) {}}'  или 'class { run = (a)=> {}}' или  'class { run(a) => {}}' и как в каждом варианте обращаться к переменным (локальным, внешним и this)
  • декларация 'function run() {;'  а вызов 'run(1, 2, 3)' потому что внутри можно 'arguments.forEach(...)'
  • function ff() {
        return
            1;
    }
    вернет undefined;
  • for(;;), for(.. in ..) или for(.. of ..) или forEach?
  • function.call или function.apply для array аргументов?
  • new Array([1,2]) - это [[1,2]], а new Array(1, 2) - это [1,2]
  • parseInt('10') - это 10, а parseInt('010') - это 8
И еще немного браузерных граблей:
  • MouseEvent.screenX, MouseEvent.clientX, window view port scrollX getBoundingClientRect и MouseEvent.offsetX
  • events конечно bubble, но если mousemove поверх div с position:absolute, то div под ним получит mouseleave
  • Element.addEventListener, или "<div click="myFunc()", или "<div click="myFunc", или "onClick = myFunc", или "onClick = ()=>myFunc()"
  • CustomEvent.type, а не CustomEvent.name
  • var scrollHeight = Math.max(
      document.body.scrollHeight, document.documentElement.scrollHeight,
      document.body.offsetHeight, document.documentElement.offsetHeight,
      document.body.clientHeight, document.documentElement.clientHeight
    ); - какое для чего и когда кого? +window.pageYOffset
нет, все нюансы бесполезно запомнинать...
проще поискать решение: google - найдется все!

воскресенье, 17 июня 2018 г.

Assert.AreEqual(DockStyle.Fill, mainPanel.Dock);

Написал я вот такой тест:

        public void Test_LayoutControls_Horizontal() {
            ...
            splitLayout.Direction = ExpressApp.Layout.FlowDirection.Horizontal;

            SidePanelLayout layout = new SidePanelLayout ();
            Panel panel1 = new Panel();
            Panel panel2 = new Panel();
            layout.LayoutControls(splitLayout, new Item("1", panel1), new Item("2", panel2));
            SidePanelContainer mainPanel = layout.Container as SidePanelContainer;

            Assert.IsNotNull(mainPanel);
            Assert.AreEqual(DockStyle.Fill, mainPanel.Dock);

Angular6: стили в "Tour of Heroes"

Display a Heroes List at angular.io - второй шаг создания приложения.
Tour of Heroes at stackblitz.com - исходники и само приложение на этот шаг описания.

Авторы предлагают такую разметку для файла src/app/heroes/heroes.component.html:


<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes">
<a routerLink="/detail/{{hero.id}}">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</a>
</li>
</ul>


<!--
Copyright 2017-2018 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->

и такие стили для файла src/app/heroes/heroes.component.css:

четверг, 15 марта 2018 г.

Какие тесты мне помогают?

Такие, которые дают ответ на вопрос "Зачем должно работать именно так?"
А многие тесты в моем текущем проекте - это только утверждения "Должно работать именно так!" без намека на причину такого поведения.

среда, 14 марта 2018 г.

Почему я часто хочу иметь автоматические тесты на варианты конфигураций у конечного пользователя?

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

Например, заказчику приложения лекго принять решение после такого моего пояснения:

среда, 17 января 2018 г.

KPI


Как их сделать?
Варианты разные (например в Стратегическое планирование) и я выбрал такую исходную формулировку Цели: продукт как инструмент для получения/увеличения доходов должен быть выгодным как для его разработчиков, так и для его пользователей. Индикаторы должны давать ответ на вопросы "продукт уже труп или очень даже живчик?", "с обоих ли сторон выгодно поддерживать/развивать продукт или нет?"
Под эту цель подходят два KPI results: доходы + расходы. Мои, как создателя продукта, и доходы и расходы его пользователей, которые я тоже буду пытаться определить разными способами.

Для этих KPI результатов через полгода (все цифры и сроки гипотетические, к реальности не имеют отношения, даже если и совпадают) хочется иметь другие значения:
- A1. Доходы разработчика продукта выросли на 20%
- A2. Расходы разработчика продукта не увеличились.
- A3. Доходы пользователей продукта выросли на ХХ%
- A4. Расходы пользователей продукта не увеличились.

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

Через полгода эти результаты будут показывать один из трех вариантов: ничего не изменилось, стало хуже, стало лучше. Или промежуточные варианты.

На каждый из этих результатов разработчик продукта может повлиять.

Сейчас 5000 клиентов продляют лицензию каждый год (5000 * $600 = $3 000 000) и еще 500 клиентов покупают новую лицензию каждый год (500 * $3000 =  $1 500 000).

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

- A1.1. Новую лицензию стали покупать больше на 20%: больше покупок новой лицензии на 300.
- A1.2. Продлять лицензию стали больше на 20%: больше продлений на 1500.
- A1.3. Промежуточные варианты между 1.1 и 1.2.

*В раскладе конкретного продукта конечно надо изучить "есть ли столько отказов от продления лицензии?", "как изменилось количество продляющих лицензию клиентов за последние 365 дней по сравнению с предыдущим периодом" и др. От этого будет зависеть приоритет изучения дальнейших шагов. TODO: разобрать эти варианты позже? Они довольно занимательны и важны.

Есть и другие варианты измерений (воронка продаж, NPS, подписчики каналов, просмотры/оценка материалов), но их я бы приложил к каждому из моих конкретных шагов в направлении A1. После того как конкретные шаги будут сделаны, эти способы помогут мне измерить эффективность шагов, оценить выбор шагов из доступных вариантов, скорректировать мои выбор/оценку/прогнозы и наверное много чего еще (TODO: написать про это позже?).

Итого мне надо получить такие изменения в продукте что бы "отказов от продления лицензии стало на 1500 меньше" или что бы "покупок новой лицензии стало на 300 больше". Промежуточные варианты или даже оба сразу тоже подойдут. Каждый вариант подразумевает Расходы, в тексте я буду их учитывать, но немного позже (TODO: а может с ними и так все понятно?).

*Можно использовать формулировку "продления лицензии стало на 1500 больше", но она зависит от нескольких факторов, ее результатом можно управлять с помощью изменения результата "покупок новой лицензии стало на 300 больше", поэтому я ее не буду использовать.

Получилась вменяемая формулировка задачи. Для ее решения я изучал (месяц, два или полгода) сценарии использования продукта, реальные заказы на разработку конечных приложений, ручные доработки в конечных приложениях, сложности использования, аналогичные продукты, провел другие мероприятия по методам Метод1, Метод2, Метод3 (TODO: нужно ли перечислять реальные способы?), выявил несколько возможностей разных изменений для A1.1 и их влияние на доходы от продукта как для разработчика, так и для клиентов.

И вот что получилось.

B1. Добавить в продукт готовую возможность просматривать и изменять данные с форматированием как в Word и хранение этих данных в базе, экспорт/импорт в разные форматы как в Word, печать этих данных

Новую лицензию на продукт с этой возможностью купят (по моим методам предсказания):
- 100 новых клиентов - каждый год после выпуска в течение примерно 10 лет
- 300 отказавшихся от продления лицензии клиентов (300 только только в этот год, потом ради этой возможности из отказников купят лицензию 50)

Ради этой возможности лицензию продлят (в дополнение к тем кто и без нее будет продлевать лицензию):
- 300 клиентов - и будут продлять дальше каждый год после выпуска в течение примерно 10 лет (+ позже сколько-то клиентов продлят из тех кто теперь решится купить)

Для этого варианта осталось оценить затраты на разработку и сопровождение этого изменения (TODO: нужно ли их расписывать в этом посте?). У меня получилось $1000 в месяц на 2 года, потом $100 потому что будут сразу готовы почти все возможности для почти всех задач и документация станет простой/понятной.

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

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

А прямо сейчас есть и другие варианты, ведь одного этого по моим предсказаниям маловато для достижения нужных изменений в KPI результатах:
B2. ... я не могу брать формулировки реального продукта и мне лень придумывать суть, вариант аналогичен предыдущему, отличия только в цифрах
B3. аналогично, отличия только в цифрах
B4. аналогично, отличия только в цифрах
B5. аналогично, отличия только в цифрах

Возможны и другие изменения, не касающиеся именно функционала продукта.

Например, такие:

C1. Увеличить информированность людей, которым подходит наш продукт. Например, через рекламу, или через наши собственные статьи о решении реальных задач с помощью нашего продукта, или через посты наших клиентов о решении их задач с помощью нашего продукта.

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

C2. Увеличить стоимость продукта - про этот вариант у меня знаний еще меньше.

С3. Другая схема получения прибыли, например с привлечением третьих участников как с рекламой на google.com.

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

Все. На этом можно считать первую половину законченной. Дальше пойдет вторая половина, третья и так далее... :-)

KPI показывает не цель, а постоянное движение к цели. Я перечислил варианты, но они не появились за полдня. Это работа предыдущего месяца, двух или за полгода. И она основана на работе по предыдущим вариантам достижения той же Цели: какие изменения были выбраны для реализации полгода назад и каков эффект от их реализации? 

Вот полгода назад я их выбрал и за полгода сделал, сейчас они стали доступны моим клиентам и ?.. Какие про них мнение у клиентов? Они помогают им зарабатывать больше денег? Они им нравятся? Им приятно работать с этими изменениями? Он довольны появлением этих изменений? Ответы на эти вопросы помогают мне определить правильно ли я выбрал и использовал методы предсказания результатов и что мне следует изменить в моей работе с этими инструментами и методами. Эта тема выглядит второй половиной. Ее мне описывать лень, она неплохо расписана в Чем занимается Product Marketing Manager в JetBrains. Там конечно слова "МАРКЕТИНГ", но общение с клиентами - это хороший способ получения обратной связи, корректировки собственной работы по выбору/планированию следующего шага для достижения нужного KPI и проверки эффективности используемых способов/инструментов.

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