Шлях до JavaScript майстерності

В 2013 почав писати оцейсписок, поки мій Python-проект ще не стартував, і мені дали тимчасово розгрібати купу JS:

  1. jQuery – ok, користуватись вмію, куди без нього.
  2. JavaScript: The Definitive Guide – за один раз не прочитаєш
  3. JavaScript: The Good Parts – за один раз прочитав, але варто перечитати.
  4. JavaScript Web Applications – можливо не найцікавіша книжка яку я читав, але з неї я дізнався про Spine.js, Backbone.js, underscore.js, та паттерн pub/sub.
  5. Прочитати про те як написання коду схоже на поезію
  6. Прочитати про об’єкт Class в Leaflet. Подумати що це варто було б окремою бібліотекою випускати, бо ж не в кожному проекті де треба ООП, треба карти…
  7. Почати модульно організовувати проекти, require.js
  8. Починати скрипти з декларації "use strict";.
  9. Пам’ятати про те що існує underscore.js, писати менше циклів.

А кінця шляху нема.

Нагадування 2014-го: І Smooth Coffescript варто дочитати.


Filed under: Кодерство, Павутина Tagged: JavaScript

Розробка керована питаннями

Чому розробка ПЗ це так важко? Тому що воно займає тисячі рядків коду і їх всіх важко набрати? Та ні, якраз навпаки, в дні коли в мене виходить написати сотні рядків коду я втомлююсь менше ніж коли пишу один, чи взагалі не пишу.

Важко звісно не набирати рядки, а ВИРІШИТИ які рядки потрібно набрати. В дні коли я пишу їх багато – це рішення просте, в дні коли мало – рішення часом взагалі неможливо побачити. І втомлюється людина від прийняття рішень, а також особливо від рішень які ще не прийняті. Навіть існує ефект Зейгарнік, який проявляється в тому, що люди схильні швидко забувати вирішені питання і закінчені справи, а незакінчені будуть триматись в мозку і займати його ресурси.

Качечка теж втомилась :)

Качечка теж втомилась :)

Тому, якщо робота застопорилась, можна спробувати застосувати модифікацію методу каченяти, яку я назвав QDD – розробка керована питаннями. Для цього потрібно написати питання над рішенням якого ви зараз думаєте в якийсь текстовий файл чи на листок паперу. І уявляти при цьому що це чат зі всезнаючим експертом, який обов’язково допоможе. Бо так і є, це час з собою майбутнім. Явне формулювання питання дозволяє сфокусувати думки, а часто зрозуміти що це не те питання яке потребує вирішення.

Якщо ще додавати до кожного запису час, і коротко записувати відповіді на запитання, можна отримати журнал який показує на що йде час розробки, і чому код написаний саме так а не інакше (бо виникали такі питання і знаходились такі відповіді). Якщо код буде написано неправильно – можна буде знайти момент в який неправильне рішення до нього привело. Якщо буде поставлена наступна задача – легше буде оцінити скільки питань і якої складності треба буде вирішити для виконання задачі. Бо розбиття роботи на пункти плану і оцінка їх по аналогії з вже виконаними пунктами – єдині відомі способи оцінити необхідний для роботи час. Для оцінки по аналогії покладаються на пам’ять, хоча журнал був би надійнішим.

Такий метод можна застосувати до вирішення інших проблем, що не стосуються коду. Наприклад до вгризання в якусь складну ідею, чи до пошуку рішення якоїсь життєвої проблеми. Багато великих питань можна розбити на менші питання, головне попрактикуватись.

Ну й наостанок дам приклад того про що я пишу – лог питань що виникають при розробці гри в “п’ятнадцять”: bunyk.github.com/blob/master/fifteen/worklog.txt. Сама гра.


Filed under: Кодерство, Психософія Tagged: психологія, розробка

Прогризання в Хаскель

Потрохи, дуже й дуже повільно гризу граніт науки з Хаскелем. Читаю “Вивчить собі Хаскела на велике щастя!“.

Книжка складна (чи то Хаскель такий), але гумор іноді веселий:

Шукати елемент у порожньому списку теж не варто, бо його там немає (і не тільки його — там немає багатьох інших елементів!)

Дійшов до розділу 8 про написання власних типів і типокласів. Ледве розібрався. Цікаво що в типів та конструкторів типів є типи (кшталти, kinds), і це не типи, як в Python, а щось інше. Не зрозуміло чому типоклас Функтор такий важливий. Ну можна виконувати над ним map. Але напевне важливий, бо десь я бачив слова “Аплікативний функтор, моноїд”, значить то десь до монад не далеко. Але дуже тішусь тим що наступний розділ буде про ввід-вивід, і я НАРЕШТІ зможу написати “Привіт, світе!”. :) Ну тобто ясно що main = putStr "Привіт, світе!", але зрозуміти що повертає putStr.

P.S. Я трохи намагався розібратись з монадами, і здається мені що в хаскелі функції не виконують побічні ефекти, але повертають щось що каже що повинні бути виконані певні побічні ефекти. Як те щось називається, і хто виконує – ще не знаю. Знаю лише що монада це три речі – тип, функція return, і ще якась функція. Що вони роблять – теж поки що не зрозуміло.

А потім може постараюсь пройти Write Yourself a Scheme in 48 Hours.


Filed under: Кодерство, Нещоденник Tagged: haskell

Асемблер x86 на Linux

Давно хотів познайомитись, але все стримувало те що в дитинстві я почав з синтаксису Intel, і хотів програмувати тут теж з синтаксисом Intel. Пройшло багато років, я забув, тому давайте вивчимо AT & T синтаксис. Потім при потребі можна перевчитись.

Ну й крім того, я знайшов книжку Programming from the Ground Up, в якій все дуже зрозуміло (як для дітей) пояснюють.

Ну дууууже коротка теорія

Перше що потрібно знати – x86 – це архітектура Фон Неймана, тобто код програми і дані зберігаються в одній і тій же пам’яті, і для комп’ютера виглядають однаково. (Щоправда операційні системи можуть обмежувати виконання лише областями з кодом, для того щоб запобігти можливим помилкам, якими можуть скористатись хитрі хакери)

Пам’ять – це довгий список байтів (можуть містити цілі числа від 0 до 255), кожен з яких має свою адресу. Адреса – це просто номер байта. Щоправда ми працюватимемо переважно не з байтами, а зі словами (в 32-х розрядній архітектурі це 4 байти, які можуть приймати значення від 0 до 4294967295). Тому що регістри процесора якраз стільки вміщають. Адреси – це теж слова (4 байти).

Найпростіша програма

Надрукуємо “Привіт, світе!”? О, ні, на ассемблері це надто складно. Давайте напишемо програму яка завершує роботу. Ага. В Unix, програма яка завершує свою роботу має повернути статус код. Статус код останньої виконаної команди можна побачити у спеціальній змінній командної оболонки: echo $?

_start – в лінкера за замовчуванням позначає точку входу в програму. Тобто адресу з якої почнеться її виконання. Можна замінити її наприклад на main, але тоді лінкер, якщо йому не вказати опцію -e main скаже:

ld: warning: cannot find entry symbol _start; defaulting to 0000000008048054

Символ відсотка позначає регістр процесора (наприклад %eax), долар позначає константу (наприклад $1, $0x80 (= 128 в шістнадцятковому записі) ).

Переривання – це місце в коді де контроль передається в якесь інше місце (в ядро). Коли ядро виконає своє переривання – воно поверне контроль нам, і програма продовжить виконання (стан регістрів може змінитись). Щоправда після системного виклику exit контроль нам ніколи не повернуть, але так й було задумано.

Щоб перевірити нашу програму, потрібно виконати команди:

as exit.s -o exit.o
ld exit.o -o exit

Перша створює об’єктний файл. Об’єктний файл – це вже код машинною мовою, але ще не до кінця зібраний. Потрібно передати його лінкеру – програмі яка вміє збирати багато об’єктних файлів в одну програму, та додавати інформацію для того щоб ядро знало як працювати з програмою.

Якщо все пройшло без помилок – можна перевірити роботу:

./exit 
echo $?

Також можна спробувати замінити код повернення в %ebx на якісь інші і подивитись результат.

Опис інструкцій

mov – це інструкція переміщення, яка має два операнди – звідки й куди.

Суфікс l означає розмір даних (long = 4 байти). Інші можливі префікси: b byte = (8 біт); s short = (2 байти (16 біт).

Багато інших інструкцій мають два операнди, як наприклад addl (додавання), subl (віднімання). Але, наприклад, інструкція div приймає єдиний аргумент, бере вміст регістрів %edx та %eax як велике 64-х розрядне число (якщо треба менше, %edx має містити нуль) ділить на переданий аргумент а тоді результат поміщує в %eax, а остачу від ділення в %ebx.

Регістри загального призначення, які можна використовувати як аргументи команд переміщення та арифметичних – це %eax, %ebx, %ecx, %edx, %edi, %esi.

Контроль ходу виконання

Давайте напишемо наступну програму, яка не просто даватиме наперед заданий статус код, а даватиме максимальне число серед заданих. Нехай ці числа зберігатимуться за адресою, яку ми позначимо data_items, і останнім числом буде нуль, щоб ми знали коли припинити пошук.

Виконання має повернути 89 (найбільше в списку). Це вже набагато цікавіша програма.

По-перше, ми маємо дані. Окрім типу .long (4 байти), ми можемо використовувати .byte, .int (2 байти), та .ascii – рядок символів, наприклад .ascii "Hello, world!\n".

По-друге, цікава інструкція movl data_items(,%edi,4), %eax. Лівий її операнд означає взяти дані з адреси data_items, але зсунутись на %edi елементів розміру 4. Тобто це як доступ до елементу масиву. Синтаксис паскудний, в Intel здається писали б data_items + %edi * 4, що виглядає зрозуміліше, але маємо що маємо.

Також, якщо ми хочемо отримати значення за адресою – теж використовуємо дужки. Наприклад – %esp – містить адресу вершини стеку. movl %esp, %eax – збереже цю адресу в %eax, а от movl (%esp), %eax – значення з вершини стеку.

Наступна незнайома інструкція – cmpl. Вона порівнює два чотирибайтові числа (суфікс бачите?), а результат порівняння записує в певні біти регістру %eflags. Про нього я дуже давно написав непогану статтю на CybWiki а потім на вікіпедії, тому в деталі не вдаватимусь.

Після порівняння зазвичай йде інструкція зробити стрибок на певну адресу, якщо виконується умова порівняння. Існують такі інструкції стрибків з умовою: je – стрибати якщо рівні, jg – якщо друге значення було більше за перше, jge – більше або рівне, jl – менше, jle – менше рівне.

incl – збільшує аргумент на одиничку. incl %edi – це те саме що й addl $1, %edi, тільки коротше й швидше працює.

Далі буде

Вже скоро ранок, а hello world ми ще так і не написали. Треба розібратись з написанням і викликом функцій, викликом функцій роботи з файлами, щоб можна було писати в STDOUT. Але це вже завтра, бо це вже й так надто червоноока публікація.

Хоча в книжці там ще йде мова про рекурсію, обробку помилок, бібліотеки функцій, та їх створення, менеджер пам’яті і інші цікаві речі.


Filed under: Кодерство Tagged: linux

HTML та LXML. Парсимо онлайн таблиці з Python

За службовою необхідністю в мене з’явилася задача організувати новий сервіс для користувачів. Сервіс простий: в нас є віртуальні площадки з різними OVZ контейнерами. Ці площадки мають своїх хазяїв. Іноді вони про них забувають. Тож треба було написати щось таке, щоби періодично перевіряло актуальність цих площадок, нагадувала власникам про їх нявність та просило би продовжити термін життя площадки або подати заявку на знищення. Все зрозуміло. Але для того, щоб це зробити, спочатку треба було актуалізувати данні по цим площадкам.

Данні в нас зберігались на сторінці в Confluence у вигляді таблиці. Таблиць на сторінці було декілька, з різною кількістю рядків і стовпчиків, з різним форматуванням, і створювались вони в різний час. Можна було б посидіти і вручну витягнути ці данні. Але, по-перше, в майбутньому доведеться обробяти і інші таблиці, по-друге, хотілося розробити інструмент, який би ці данні готував до того аби запхнути їх в базу, і потім використовувати їх. Тож: Confluence, HTML, LXML.

Timeout decorator

Декоратор який використовуючи сигнал Unix SIGALRM перериває роботу функції якщо та працює довше ніж задане число секунд:

import signal

class TimeOut(Exception):
    def __init__(self, msg='Time out error'):
        super(Exception, self).__init__(msg)

def on_alarm(signum, frame): # при надходженні сигналу кидати виняток
    raise TimeOut()

def limit_time(t, default=None):
    signal.signal(signal.SIGALRM, on_alarm) # встановити обробник сигналу

    def decorator(f): 
        def decorated(*args, **kwargs):
            signal.alarm(t) # попросити ОС прислати нам сигнал через t секунд
            try:
                return f(*args, **kwargs)
            except TimeOut:
                return default
        return decorated
    return decorator

import contextlib
# Дякую Алекс!
@contextlib.contextmanager
def time_limit(t):
    signal.signal(signal.SIGALRM, on_alarm)
    signal.alarm(t)
    try:
        yield
    except TimeOut:
        pass


import time

@limit_time(5) # працювати не довше 5 секунд
def test():
    for i in range(10):
        print i
        time.sleep(1)

test()

with time_limit(5):
    for i in range(10):
        print i
        time.sleep()


Filed under: Кодерство Tagged: linux, Python

Windows performance counters

Публікується в рамках розгрібання чернеток. Тим хто не займається адмініструванням Windows буде зовсім не цікаво, проходьте далі…

Одного разу переді мною поставили задачу перевірити можливість отримання певних метрик загальною кількістю біля 200 штук для двох видів користувачів для трьох версій операційної системи. Я сміливо взявся за роботу, розваживши що якщо написати скрипт який в одному циклі проходиться по метриках, а в іншому – по хостах та користувачах, то це все можна зробити швидко. Але є одне але. :) Точність оцінювання необхідного часу сильно падає якщо ти чогось не знаєш, і ще більше падає якщо ти не знаєш що ти чогось не знаєш.

Наприклад я довго не міг зрозуміти чому не працює:

PS C:\Users\Administrator\Documents> Get-Counter '\Disk Read Bytes/sec'
Get-Counter : The specified counter path could not be interpreted.
    + CategoryInfo          : InvalidResult: (:) [Get-Counter], Exception
    + FullyQualifiedErrorId : CounterApiError,Microsoft.PowerShell.Commands.GetCounterCommand

А виявилось що performance counter повинен мати формат:

[\\<ComputerName>]\<CounterSet>[(<Instance>)]\<CounterName>

, де необов’язковим є лише ComputerName та іноді Instance, і в мене воно просить уточнити якого диска читання я хочу отримати. Наприклад:

PS C:\Users\Administrator\Documents> Get-Counter '\LogicalDisk(*)\Disk Read Bytes/sec'

Timestamp                 CounterSamples                                                                                      
---------                 --------------                                                                                      
29.04.2014 20:01:15       \\win-dl46o26fd8h\logicaldisk(harddiskvolume1)\disk read bytes/sec :                                
                          0                                                                                                   
                                                                                                                              
                          \\win-dl46o26fd8h\logicaldisk(c:)\disk read bytes/sec :                                             
                          8209,39607393418                                                                                    
                                                                                                                              
                          \\win-dl46o26fd8h\logicaldisk(_total)\disk read bytes/sec :                                         
                          8209,39607393418     

І кількість таких проблем виправляється лише постійною освітою, тому нею й займемось.

Get-Counter

Основне варте уваги джерело інформації яке я зміг викопати – Microsoft Technet на жаль. Ну але там теж щось пишуть, хоча й занудно.
Read more »

Проблема з програмістами, що “вище середнього”

Liaoning School by kattebelletje

Сьогодні попалася на очі досить таки цікава стаття, вирішив перекласти, оскільки давно вже нічого не публікував у блог. Звісно, речі описані там як би й очевидні, але в той же час зазвичай поки не ткнуть носом — цього не помічаєш. Коли у мене було всього три роки професійного досвіду програмування я теж було почав скочуватись в цю прірву, але я вчасно зав’язав :)

Примітка: тим хто читав або чув про чудову книжку “Pragmatic Thinking and Learning” деякі твердження можуть здатися протиріччям, але це не так. Поняття експерта там дещо ортогональне тому що описано тут, плюс там теж згадується про пастку “спочивання на лаврах”.

Оригінал: The Problem With ‘Above Average Programmers’
Автор: Dave Rodenbaugh

Швидко! Дайте відповідь на наступне питання не роздумуючи:

Як би ви оцінили ваші навички з програмування? (Нижче середнього, Середнє, Вище середнього)

Психологічні досліди проведені в різних групах показали, що більше 90% всіх програмістів вважають свої навички “Вище середнього”.

Як ви розумієте, так бути не може. Грубо кажучи, в групі зі 100 людей 50% вище середнього, а 50% — нижче. Цей ефект відомий в психології як “Ілюзія переваги”. Його спостерігали та задокументували у багатьох областях, і навіть знаючи про цей ефект ви ймовірно все одно дасте відповідь “Вище середнього”.

Сміху заради спробуйте спитати це у кожного знайомого вам програміста. Не питайте їх у групі, питайте один-на-один щоб отримати більш “чесну” відповідь. Ви отримаєте схожі результати навіть від людей, які не знають як запрограмувати щось дійсно нетривіальне (насправді це ефект Даннінга-Крюґера, але вони пов’язані). Це епідемія нашої професії.

А тепер уявіть на хвилинку, що ви і справді “вище середнього”. Просто мужик! Рок-зірка. Бог поміж смертних. Клави схиляються в реверансі, коли ви проходите поруч, а труби грають туш, коли ви комітите на Github.

Якщо ваші знання вище середнього, то ви експерт в тому що ви робите. Називати себе експертом дуже приємно — ви здобуваєте повагу, шану та престиж будучи ним.

Бути експертом означає що ви знаєте все про вашу область. На жаль, це часто означає, що ви станете ледачим. Це означає, що ви станете спочивати на лаврах і сидіти дупцею на м’якому дивані думаючи, що ви кращий за багатьох інших замість того, аби працювати над цим. Ваш досвід стане вашим тягарем, тому що ви перестанете хоч намагатись вчитись. Не сьогодні, але досить скоро.

Натомість, чому б не розглянути іншу можливість? Ви — середняк, або (боже збав!) нижче середнього. Окрім пораненої гідності, яку ви можливо будете переживати, подумайте про справжні переваги:

  • Припускаючи що ви не найвправніший, у вас є стимул стати ним
  • Припускаючи що ви не найрозумніший, у вас є можливість вчити щось нове
  • Припускаючи що ви не найкращий у своїй справі, ви будете працювати краще, щоб вдосконалити себе

Можливо ви чули про “розум початківця”? Короткий його зміст сказаний майстром Дзену з типовою лаконічністю коану:

В голові початківця є багато можливостей, в голові експерта є лише кілька.

Пастка самоназви себе “експертом” в розробці софту означає, що ви запираєте себе у певну мову (Java, Ruby, PHP), певну сферу (медичні пристрої, соціальні мережі, ігри), певну спеціалізацію (embedded, enterprise, тощо). Коли ви напрацюєте цей досвід, вас буде переслідувати страх помилки, коли ви вийдете за свою зону комфорту. Зі своїм золотим молотом досвіду все навкруги здаватиметься цвяхом. Ви не будете думати про викрутки та інші адекватні інструменти оскільки ви про них не знаєте, або не вмієте користуватись.

Саме тому починаючи новий software-проект ви часто дивуєтесь чому “досвідчені програмісти” не можуть взяти X, ви ж вивчили X всього за кілька днів. X може бути чим завгодно: замикання, об’єктно-орієнтоване програмування, фреймворк Ruby on Rails, програмування на Haskell. Врешті-решт, це не має ніякого значення, голова експерта забита застарілими знаннями. Голова початківця відкрита та вільна від перепон.

Коли ви експерт, вчитися важче. Тому бути “досвідченим програмістом” небезпечно.

Тож яка ж першочергова річ, яку можуть зробити програмісти? Почати з того, аби вважати свій рівень нижчим середнього. Вийти за зону комфорту. Бути “найсереднішим”.

Маестро ніколи не перестає вчитись, і ви не переставайте також.

Вступ до PowerShell

Зробив на роботі доповідь по PowerShell:

І не переживайте, там з восьмої хвилини в конференції нарешті настає тиша. :)

Презентація зроблена на основі вікіпідручника з PowerShell, який порізано на слайди і показано за допомогою deck.js (хоча про технологію якось іншим разом).

Це приклад того як доповіді робити не варто. Не варто змішувати підручник і презентацію, на презентації повинен бути лише код, картинки і максимум одне-два слова тексту. І якщо все таки якийсь текст вже є – не можна його читати. Ваші слухачі грамотні все таки.

З іншого боку – краще зробити щось неідеально, ніж не зробити ідеально. :)

Є інший приклад: Александр Соловьев — Functional Reactive Programming & ClojureScript. Чувак не париться, лише 16 слайдів, видно що тема його вставила, але пояснити він її може заледве на пальцях. Проте я таки зрозумів що FRP – це як в Excel, і при цьому не заснув.

P.S. Наступна доповідь буде кращою. :)


Filed under: Кодерство, Конспекти Tagged: освіта, робота, windows

Заблоковано завантаження змішаного активного вмісту

З версії 23 (квітня 2013) Firefox забороняє завантаження змішаного активного вмісту, тобто ви не можете завантажувати на отримані через https сторінки скрипти (активний вміст) по http. Тому, якщо ви отримуєте таке повідомлення:

Заблоковано завантаження змішаного активного вмісту
"http://modernizr.com/downloads/modernizr-latest.js"

Треба якось захостити бібліотеку на сервері з https.

Або зайти на сторінку about:config і поставити налаштування security.mixed_content.block_active_content в false.


Filed under: Кодерство, Павутина Tagged: JavaScript