Tag Archives: Лайфхаки

Як написати свій букмарклет?

Букмарклет (bookmark) – це слово створене поєднанням слів bookmark (закладка) і applet (application (застосунок) + зменшувальний суфікс -let). Таким чином правильним перекладом bookmarklet було б “закластуночок” (чи “застокладочка”), але ви цього краще не кажіть Юрку Зеленому. Але я відхиляюсь. Отож, букмарклет, це маленька програма що міститься в закладці.

Як її туди помістили? Ну, виявляється браузери крім протоколів http, ftp, ітп, розуміють такий протокол як javascript. І коли отримують посилання з цим протоколом, при кліку по ньому не змінюють сторінку, а виконують його href як код JavaScript. Щоб побачити приклад простого букмарклету, створіть документ bookmarklet.htm, і помістіть в нього такий код:

<html>
<head><meta charset="utf-8" /></head>
<body>
<a href="javascript:
    alert('Привіт!')
">Мій букмарклет</a>
</body>
</html>

Якщо відкрити його в браузері, ви побачите чисту сторінку з єдиним посиланням Мій букмарклет, яке при кліку буде показувати повідомлення “Привіт!”. Якщо перетягнути це посилання на панель закладок в браузері, то тепер ви зможете в будь-який момент отримати привітання на будь-якій сторінці яку дивитесь, досить лише натиснути букмарклет.

Але це не дуже корисний букмарклет. Щоб він робив щось корисніше, досить замінити код в рядку 5, на якийсь корисніший.

Наприклад є такий сайт – lib.rus.ec. Вони хоч мають домен еквадору – але москалі, і коли відкрити їх сайт, то вискакує повідомлення, яке блокує доступ до сторінки, і просить грошей за чужі книжки. Я переконаний що в цьому випадку дозволяється використати принцип “грабуй награбоване”, і додати в букмарклет такий код:

 document.getElementsByClassName('lsp-overlay')[0].remove()

І тоді при кліку по букмарклету це вікно пропадатиме. Клас, правда? (Не забудьте забрати виклик alert() який ми написали там раніше)

Але давайте зробимо ще щось складніше і корисніше. Давайте зробимо букмарклет, який оформлює посилання на веб-сторінку в форматі вікіпедії cite web, і дає її нам в якомусь вікні. Це такий шаблон, який гарно оформлює посилання, але заповнювати його руками – ще та морока.

Для букмарклетів є кілька правил. Їх код все таки міститься всередині атрибуту елемента HTML, і повинен відповідати стандартам цієї мови. Наприклад всі подвійні лапки """ (ну ви зрозуміли), повинні бути заміненими HTML-кодом ". Крім того, перехід на новий рядок вважається еквівалентним пробілу, тому однорядкові коментарі можливі лише в кінці скрипта:

alert('Це вискочить');
// alert('Це не вискочить бо закоментовано');
alert('Це теж не вискочить бо коментар продовжується');

Ну і тому що ввесь скрипт здається браузеру написаним на одному рядку – бажано шанувати крапки з комою.

Якщо ми хочемо написати великий букмарклет, який можливо використовуватиме jQuery, та інші бібліотеки, нам захочеться їх якось підвантажувати. Але, віднедавна в адміністраторів серверів з’явилась нова можливість збільшувати безпеку вводячи обмеження на джерела з яких на сайт завантажуються ресурси – Content Security Policy, тому такі букмарклети можуть працювати не всюди. Можливо доведеться все переписати, мініфікувати і запакувати, але на всяк випадок, ось вам код підвантаження скрипта:

(function () {
    var script = document.createElement('script');
    script.src='https://gist.githubusercontent.com/bunyk/6ae97e5c3de490cfb4a1/raw/b7fcfde5c40314262893761418a6a25dd6ed0ce8/cite_web.js';
    document.body.appendChild(script);
}());

Подібним чином вже з того скрипта ми можемо підвантажити jQuery та наприклад CSS.

Я тут наковбасив трохи JavaScript, який можливо не на всіх сайтах працює, і не всі дані статті витягує, але на моєму блозі він дає щось подібне до цього:

cite_web

Щоб поставити собі такий, перенесіть оце посилання в закладки: “{{cite web|…“, а тоді в контекстному меню закладки натисніть “Властивості”, чи “Редагувати”, і замініть текст на

(function () {
    var script = document.createElement('script');
    script.src='https://gist.githubusercontent.com/bunyk/6ae97e5c3de490cfb4a1/raw/3102c3e285c6e24a9aed98d1bc7f0b7abeda20fc/cite_web.js';
    document.body.appendChild(script);
}());

Ось код:


Filed under: Кодерство, Павутина Tagged: Лайфхаки, вікіпедія, JavaScript

Кулінкулятор

2014-06-02_23-59-43_642Написав калькулятор для обчислення енергетичної цінності, ціни і терміну зберігання страв що створюються з набору наперед відомих інгредієнтів за всілякими рецептами.

Наприклад рецепт на одну дію:

> print(кукурудза + тунець)
Кукурудза ніжна вакуумована стерилізована і
Консерви рибні. Тунець подрібнений стерилізований.
Ціна: 32.48 грн. Вихід: 470 грам
Енергетична цінність в 100 г продукту: 487.6 кДж
білки - 8.34 г, жири - 1.54 г, вуглеводи 15.79 г. 
Після відкриття зберігати не більше ніж: 48 год

Кожен продукт окрім додавання ще можна множини на скаляр. Але інгредієнти звісно треба задати наперед:

кукурудза = Product(
    bar_code=4824024004211,
    name='Кукурудза ніжна вакуумована стерилізована',
    producer='Бондюель',
    country='HU', 

    price=12.49,
    amount=340, # g
    
    # g per 100g:
    proteins=3.1,
    carbohydrates=21.8,
    fats=1.6,
    energy=505000, # joules

    opening_shelf_life=48, # hours
)

тунець = Product(
    bar_code=4824024002439,
    name='Консерви рибні. Тунець подрібнений стерилізований.',
    producer='Chotiwat manufacturing',
    country='TH', 

    price=19.99,
    amount=130, # g

    # per 100g:
    proteins=22.06,
    carbohydrates=0.07,
    fats=1.4,
    energy=442000, # joules

    opening_shelf_life=48, # hours
)

Але ідеальним для мене буде сайт рецептів, на якому писатиме: макарони в твоєму холодильнику пора буде викинути через 5 годин, тому сьогодні на вечерю ти їстимеш їх. Для повного денного раціону тобі бракує ще 500 грам яблук, найшвидше їх купити буде на Стрийському ринку де вони вчора коштували 8 грн/кг, тому очікуємо що це коштуватиме тобі сьогодні 4 грн.

Або хоча б на вікіпедії й на вікіпідручнику завести такі таблички, щоб кулінарити було легше.


Filed under: Кодерство Tagged: Лайфхаки, Python

To be the best…

To be the best, we gotta pass the test
We gotta make it all the way
To the top of the mountain!

Tenacious D

Пройшло вже більше 10-ти років відколи я вперше побачив IDE Turbo Pascal 7.1. І впевнений що Microsoft житиме і працюватиме щонайменше поки Андерс Гелйсберг в них працюватиме.

Але програмувати мені чомусь досі важко як і тоді. І то, тоді було легше, тому що я не займався цим по 50 годин на тиждень і енергії було більше. Хоча, 10 років – немалий термін, і Пітер Норвіг пише що за 10 років вже можна було б навчитись. Розмірковувати чому в університеті мене нічого не навчили я тут не буду. Досить того що зараз я рухаюсь. Наприклад здається вже осягнув поняття співпрограми (coroutine). А рік тому мав шок – як так, мене в університеті вчили лише про підпрограми та функції, а тут на тобі – підпрограма є лише частковим випадком співпрограми. :)

Зараз інша проблема. На роботі є кінцевий термін виконання проекту. Якось я задав питання “А зробити дешево чи правильно?” і задача на 2 години стала задачею на 3 дні. Вчора знову задав таке дурне запитання. Сьогодні накодив дешево – на нехай мене на рев’ю виховають. Все одно ще всі баги не пофікшені.

Почитав StackOverflow. Щоб стати кращим Python-програмістом треба прочитати Real World Haskell. Цікава ідея, так і зроблю якщо звісно інші ідеї не прийдуть в голову.

І випадково натрапив на взагалі іскрометну історію:

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

Він мав дві інші примхи: випукле дзеркало вмонтоване над монітором “Щоб знати хто підглядає”, та нерегулярне випадкове вставання з крісла для того щоб швидко зробити десять віджимань. Він пояснював останнє як “Компілятор знайшов помилку в коді. Це покарання.”

Опукле дзеркало – цікавий приклад совка, але от покарання – можливо має певний з точки зору фізіології сенс.


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

Журнал роботи в Google Sheets та розширення його функцій з JavaScript

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

Власне спочатку я хотів завести табличку по методології Pomodoro. Але, виявилось що Pomodoro – це занадто складно коли тебе три наради на день, якщо не рахувати переписок зі співробітниками в Skype. Тому я вирішив просто записувати час початку виконання і час закінчення.

В Google Sheets є дві корисні комбінації клавіш:

  1. Ctrl + ; – вставляє в клітинку дату
  2. Ctrl + Shift + ; – вставляє в клітинку час. В мене чомусь в форматі AM/PM.

Цього було б досить, але рахувати тривалість задач доводиться вручну. Незручно. Якщо є табличка:

A B C D
1 Time started Task Time finished Duration
2 1:32 PM Project A daily stand-up 1:51 PM 0:19

Хочеться щоб колонка D заповнювалась формулою. Але якщо написати в D2 =C2 - A2, воно видасть: “#VALUE!” – Помилка: не число: 1:51 PM. Тому треба використати функції.

Десь я чув фразочку що електронні таблиці – це функціональна мова програмування. Ах. :) Функцій там купа. Клітинок аби зберігати результати їх роботи – теж досить. Але вчити всі ті функції – ну їх.

На щастя Google Docs можна скриптувати за допомогою JavaScript! Ну й правда, не Visual Basic-ом ж користуватись у браузерному застосунку.

Як ми це робимо? Натискаємо “Інструменти” -> “Редактор сценаріїв”. Відкриється онлайновий редактор коду. Вставляємо туди щось таке:

// (c) Salman A     http://stackoverflow.com/a/1788084/816449
function date_diff(date1, date2) {
  if (date2 < date1) {
    date2.setDate(date2.getDate() + 1);
  }
  return date2 - date1;
}

function fmtmsec(msec) {
  var hh = Math.floor(msec / 1000 / 60 / 60);
  msec -= hh * 1000 * 60 * 60;
  var mm = Math.floor(msec / 1000 / 60);
  msec -= mm * 1000 * 60;
  return hh + ':' + mm;
}

function parsetime(cell) {
    var part = cell.match(/(\d+):(\d+)(?: )?(am|pm)?/i);
    var hh = parseInt(part[1], 10);
    var mm = parseInt(part[2], 10);
    var ap = part[3] ? part[3].toUpperCase() : null;
    if (ap === "AM") {
        if (hh == 12) {
            hh = 0;
        }
    }
    if (ap === "PM") {
        if (hh != 12) {
            hh += 12;
        }
    }
    return new Date(2000, 0, 1, hh, mm, 0);
}

function time_diff(arg1, arg2) {
  try {
    arg1 = parsetime(arg1);
    arg2 = parsetime(arg2);
  } catch (e) {
    return '';
  };
  return fmtmsec(date_diff(arg1, arg2));
};

function test() {
  Logger.log(time_diff('9:12 PM', '10:30 PM'));
}

Даємо модулю назву, на зразок Time diff, зберігаємо. В нашій табличці відкриваємо “Інструменти” -> “Менеджер сценаріїв” та переконуємось що наш сценарій там видно.

Тепер, в клітинці D2 можна писати =time_diff(A2;C2). І не поставте кому між аргументами. Буде синтаксична помилка яку я довго шукав в JavaScript, в той час як виявилось що проблема була в записі формули. І це ніби все.

Так просто що мені аж сподобалось.


Filed under: Інструменти, Кодерство, Павутина Tagged: Лайфхаки, JavaScript, робота