[Перевод] Нотч прекращает разработку 0x10c

image
Маркус Перссон, известный как Нотч, сообщил, что он прекратил работу над 0x10c.
«Nope, their are no future aspirations for 0x10c. I'm going to make small games for the rest of my life. If someone on the office wants to carry it on they can.»

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

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

Возможно, группа фанатов сможет продолжить разработку 0x10c, хотя и не ясно, как они получат доступ к уже созданному Нотчем коду. Команда Mojang продолжит выпускать обновления для Minecraft и Scrolls.



Для интересующихся:


Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Стартапер «с нуля» 3, в инкубаторе


Вначале было около 150 стартапов. Я дошел до финала. Один из 10. Дальше решение зависело от мнения международного совета директоров. Выбрали семерых, но я не оказался в их числе. Это был отбор в первый цикл инкубатора Хэппи Фарм.

Через пару месяцев во всеукраинской битве стартапов я занял первое место из 330. Главный приз — внеочередное зачисление в резиденты инкубатора второго цикла. Так я попал в Хэппи Фарм со своим стартапом NextMusic.TV. О моем опыте акселерации и написана данная статья.


Эта статья — продолжение серии моих предыдущих статей под общим заголовком «Стартапер «с нуля»»:
Здесь статья №1.
А здесь — №2.

Середина мая 2013
Как первый ранее отобранный резидент я готовлюсь с 20 мая начать акселерационную программу. Но не всё так просто.

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

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

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

При этом постоянно переделываю презентацию. Финальный вариант готов всего за 24 часа до решающего дня.

Решающий день #1
Между собой в стартаперском кругу мы этот день прозвали “Прохождением врачей в военкомате”. Преддверие демо-дня. Каждый получил чеклист со списком отделов инкубатора (Финансовый, PR, Юридически и т.д.), которые он должен пройти и поставить подпись. Народу очень много. Часть из других стран проходит собеседования удаленно через скайп. Дело затянулось до поздней ночи. Финальный отдел — это презентация перед CEO инкубатора Анной Дегтеревой и председателем совета директоров Игорем Шойфотом.

Очередь дошла до меня ближе к 18:00. Моя презентация не вызвала бури эмоций у зрителей, получив от Игоря Шойфота мягкий комментарий, что я могу и лучше. На этом день закончился с небольшим осадком на душе.

Меняю всё
Приняв отзыв близко к сердцу, решил выжать из себя максимум — презентовать не под PPT с переключающимися по команде слайдами, а под видеоряд. Это значит, что мой голос вживую должен быть синхронизирован с картинкой секунда в секунду. Видео делаю и правлю на Powtoon.com. Снова гоняю себя по презентации круглые сутки.

В финальном варианте принимаю рискованное решение включить в середине видео пару кусочков музыки. Звучит круто и живо. Посреди презентации вдруг откуда-то в тему питча начинает играть музыка. Круто, но если выйдет лажа с колонками или воспроизведением видео, то «Шеф, всё пропало!».

Узнаю у СТО инкубатора Карполана, порядок ли с колонками. Если что, готов свою аудио-систему принести. Дополнительно в день демо пораньше проверяю, играет ли видео и звук с главного компьютера. Вроде бы порядок. На всякий случай записал кусочки музыки себе на смартфон для запуска вручную.

Демо
Народу отобрали порядочно. Если на демо первого цикла было всего 10 команд и все с Украины, то здесь их штук 40 со всех концов советского союза.

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



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

Оглашение результатов
Все стартаперы скопились в конференц-зале, выжатые как лимоны, но продолжающие жить на адреналине. Входит Анна и совет директоров. Начинают оглашать списки, по убыванию, сколько менторов какой захотели проект. В общем выбрали 12 команд. Менторами NextMusic.TV захотели стать Браян Сатианатан (Turner Broadcasting) и Игорь Рябенький (Altair Ventures, всем известный ангел-инвестор). Ура! Победа! Начало программы через пару дней. Можно паковать чемоданы.

День до начала
К этому дню необходимо было определиться с тем, кто будет твоим основным ментором (входит в 15%, которые получает инкубатор), а кто дополнительным (размер долевого участия оговаривается индивидуально), если конечно хочешь больше одного. Я посоветовался с партнером СТО Андреем Транским и мы решили брать всех оптом.

Далее — личные беседы. Каждый говорит, чем может помочь, высказывает идеи. После, с выбранными менторами составляем и утверждаем вместе план на 2 месяца инкубации. План получился огромным: мобильные версии для Android, iOS, новый дизайн/UI/UX, смена фокуса, увеличение базы музыки с 250 тыс. до 2х миллионов, что означает переделку архитектуры, перегоны больших объемов данных…

Стиснем зубы и прорвемся. Для этого и пришли.

В этот же день нас поселяют в люксовые номера гостинницы.



Распорядок дня
С первого же дня ты осознаешь, что попал в центр урагана, чем-то похожий на казарму, чем-то — на
пионерлагерь, чем-то на восточный рынок, чем-то на что-то ни на что не похожее. Каждый день расписан впритык.
Утром в 8:00 — завтрак.
Потом — мастер-класс от очередного ментора-гостя-мега-монстра из Силиконовой Долины (в большинстве случаев), реже — от мега-монстра с территории Советского Союза.
Далее — индивидуальные консультации по полчаса-час с каждой командой.
Обед в 13.00.
Далее — бесконечные задачи от инкубатора, юридические процедуры, питчи, уроки английского.
Ужин в 18:00.
11 часов рабочего бодрствования уже прошло. А нужно еще план свой выполнять, продукт развивать, применять избранные советы гостей и менторов, общаться с пользователями, репетировать и улучшать питч. И для этого остается только вечер и ночь. А если не выполнишь задуманное, зачем ты вообще сюда пришел и, что будешь потом питчить инвесторам? «2 месяца я учился»? Это никого не интересует. Учеба — это не цель, а средство. Все здесь для строительства успешных, многомиллионно прибыльных компаний.

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

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

Решили выйти с этой ситуации таким образом. Я продолжаю делать веб-версию. Андрей помогает мне с задачами, которые можно сделать автономно от ядра. Самая большая — это объединить базу артистов (миллион записей), треков (12 миллионов) с ютубовским API. В итоге получилась база на 50 млн. записей, которую еще нужно было обработать и привести к работающему виду. Этим уже занимался я. А Андрей со своим другом Игорем (наш новый участник команды) полностью сконцентрировались на мобильных и десктоп версиях (мало нам задач, решили еще и десктопы сделать).



Теперь мы друг другу не мешали и каждый смог выкладываться по максимуму.

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

На грани
Стали ли мы успевать всё до вечера? Нет мы работали все два месяца по 19 часов в день.
А в периоды, когда нужно было срочно подключать новую базу и переделывать всю архитектуру, ибо запросы обрабатывались по 30 секунд, а без готовой БД вскоре нечего было бы делать Андрею с Игорем, тормозился весь план, мне приходилось фигачить по 40 часов одним залпом, отсыпаясь раз в двое суток.

Это реально было на границе физических возможностей. Очень сложно. Много злости и рычания на самого себя, какого фига так медленно. В этом плане мне очень помогал наш же NextMusic.TV. Я выбирал Очень плохое настроение, Очень энергично, и впервые в жизни получал удовольствие и заряд дикой энергии от треш-спид-хардкор-дез металла. В фейсбуке я так и написал: «Если бы не NextMusic.TV, то не было бы NextMusic.TV.».

В таком режиме всё шло с недели две, пока я ни закончил и вздохнул с облегчением. Но мне бы никогда не удалось сделать правильную оптимальную на сегодняшний день архитектуру, если бы мне не помог сам Андрей, Карполан (СТО ХэппиФарма), который не поленился провести для меня часовой ликбез, и Валентин (СТО стартапа Instudies.com) — супергений супербыстро решающий вопросы, над которыми я сидел по пол дня.



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

Благодаря моим коллегам по казарме, вопросы решались значительно быстрее. С дизайном, UI, инструментариями мне помогли Миша (CEO Jamroo.ms) и Егор (CEO и дизайнер Instudies.com). Андрей по iOS консультировался у гения Саши из KartoonArt.com. Идеи для сервиса и баг-репорты поступали ото всех. Когда мне нужно было проверить новый дизайн на юзабельность, я подошел к каждому и никто не отказал мне в помощи.



Подготовка к презентации
Этому вопросу в инкубаторе было посвящено примерно 20% времени. Каждую пятницу проходили общие питчевальни. По инициативе жителей инкубатора под предводительством Паши из Razmir.com был также организован вечерний клуб «Персик» (peach~pitch), цель которого — питчиться друг перед другом, привыкать чувствовать себя раскованно.

Каждый раз, когда приезжал гость-ментор, мы представлялись короткими питчами по 30 секунд — минуте. По пятницам презентовали 3х минутный питч.

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

Мне очень повезло в этом плане. На презентацию я инвестировал гораздо меньше времени, так как занимался ей уже пол года до этого, посещал все открытые мастер-классы ХэппиФарма и не только.

Тем не менее мой питч было куда улучшать во время инкубирования. Особенно мне понравились мастер-классы и личные рекомендации по этому поводу от Виталия Голомба, ментора «500 startups».



Правильность английского аккуратно поправлялась Биатрис Дэй, нашим волшебным преподавателем Английского.

Это всё тоже требовало времени, поэтому я принял решение для оптимизации процесса пока записывать все рекомендации, а потом за неделю до демо-дня всё применить, переделать видео и отрепетировать.

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

Уже по прошествии инкубации я осознаю еще дополнительные плюсы от кампусности. Во-первых — это полная концентрация на проекте. Абсолютно всё помогает тебе. Во-вторых — это сближение с командой. Мы с Андреем были знакомы лишь виртуально. Пребывание под одной крышей вместе в инкубаторе укрепило нашу команду, превратило её в настоящую команду друзей.



Вторая часть
После первых двух супер-напряженных недель рабочий график немного попустило. Теперь я заканчивал работать в 2 ночи, наслаждался сном и просыпался под будильник в 7 утра.

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

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

Первый — это грантовый фонд Александра Кардакова, принявший решение выделить грант 6 тысяч долларов одному из резидентов ХэппиФарма стартапу EyeDoc (sightwatcher.com).

Второй случай произошел, когда инкубатор посетил ангел-инвестор из Бостона Семен Дукач, известный также по голивудскому фильму «Двадцать одно» (сценарий которого был написан на реальной истории Семена). Его, как и всех менторов, пригласила в инкубатор наша главная по обучающей программе пионер-вожатая Алёна Калибаба :). Оторвавшись неохотно от своих дел, все собрались в конференц-зале и по очереди рассказали свои питчи. Потом были личные беседы. Со мной и Андреем Семен захотел пообщаться отдельно. Его заинтересовал проект, наша команда и прямо на месте он принял решение инвестировать в нас $15К за 2% доли в компании.

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



Виза
Для участия во втором этапе акселерации (стажировка в США) необходимо получить визу. Но получение визы было изначально зоной неизвестности. В прошлом сезоне часть получила визы, часть — не получила. И взаимосвязей некто не понял. Посольство США не сообщает причину отказа.

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

Первыми пошли команды с России, Беларуси и Молдавии, чтобы получить ответ до окончания инкубации. Человекам десяти передо мной дали визы. Всё выглядело безоблачно. Потом одному дали отказ. Безоблачность исчезла. Через пару дней — мой черед.

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

«Ага, значит вы из ХэппиФарм?» — первый вопрос от консула.
«Да», улыбаясь ответил я.
Консул: «И вы занимаетесь построением прибыльных компаний?».
Я: «Точно :)».
Потом еще пару вопросов в таком духе и «Чем занимается ваша компания?».
Мой рассказ был перебит «Если вы из ХэппиФарм, то должны рассказать на английском.».
Ок. И рассказал на английском, заодно ответив на вопрос о ценности инкубатора лично для меня.
По ощущениям вся беседа заняла минуты полторы и закончилась «Ok. Your visa is approved.».

Вот и отлично.

Не тут то было
Но история с визой на этом не закончилась. 19-го июля в разгар второго съезда совета директоров, позвонил некто из посольства и сообщил, что моя виза будет анулирована и выдан пожизненный запрет на въезд в США. Причина в том, что я подозрительный чувак, менявший два раза фамилию. И вообще моя мама уехала в США, осталась там жить, посрочила визу и устроила скандал, а папу завернули на границе при попытке нелегальной эмиграции.

Веселая информация в подходящий день.

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

Папа прислал оперативно, а мамина виза в США стоит в старом паспорте, от которого остались только ксерокопии. При этом сама мама заграницей, а ксерокопии в закрытой квартире. Придется ломать дверь.

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

Демо-день
Аншлаг-Аншлаг-Аншлаг. Количество посетителей зашкаливало. Выбранное нами случайно место под кондиционером стало играть роль оазиса.

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

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

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



Виза. Продолжение...
В понедельник звоню человеку с посольства. Его нет и не будет целую неделю. Странно.

Аня Дегтерева и весь инкубатор со своей стороны под предводительством Биатрис Дэй составляют вместе письмо-опровержение для посольства по всем законам дипломатии, с подкреплением изобилия фото и видеоотчетов. И отправляют на все электропочты посольства США. Через пол часа приходит ответ, что виза мне открыта, можно забирать.

#@###@&#!

На следующий день поехал за паспортом, в котором красовалась виза до 2018 года.

Аривидерчи
Финальный день мы в инкубаторе провели очень сентиментально, как последний день в пионерлагере. У каждого появилось более 20 друзей-единомышленников. Слова благодарности, танцы, беседы и день рождения Марины из lonely-walls.com.

Не лишним будет еще раз высказать свою безмерную благодарность всем резидентам второго цикла, менторам, а также всем, кто организовал и принимал участие в волшебном втором цикле акселерации в Happy Farm.

После инкубатора
Первый этап инкубации окончился. Второй в США мы решили с Андреем не брать, в обмен на сохранение части доли. На освободившиеся около 6% мы собираемся привлечь еще 2-3 инвестора на $40-50K для роста за 2-3 месяца до 10 000 активных пользователей в неделю. Сейчас мы продолжаем расти со скоростью около +300 активных в неделю. По достижению цели можно будет привлекать следующий раунд ~$250К.

Недавно мы подключили учет персональных вкусов и дали пользователям власть влиять на категоризацию музыки. В ближайших планах — запуск публичных версий мобильных приложений на iOS, Android & Windows Phone.

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



Продолжение следует…

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Ответ Ильи Массуха (ФИД, РОИ) на открытое письмо по петиции об отмене 187-ФЗ

Сегодня на портале «Фонда информационной демократии» появился официальный ответ на открытое письмо, опубликованное мной на Хабре.

image

Ответ на открытое письмо по петиции об отмене 187-ФЗ

Оригинал обращения — habrahabr.ru/post/189652/

Уважаемый Артём!

Спасибо за письмо и за гражданскую позицию. Постараюсь ответить на Ваши вопросы по порядку:

1) По достижению порога в 100 000 голосов, инициатива должна быть передана в экспертную рабочую группу с указанием, в том числе, сведений о проголосовавших «за» и «против», о распределении голосов по регионам России. В случае продолжения голосования такие сведения перестают быть актуальными сразу после отправки инициативы. Не сомневаясь в том, что все инициативы, преодолевшие рубеж в 100 000 голосов, либо 5% от населения субъекта или муниципалитета, имеют потенциал дальнейшего сбора голосов, по действующему регулированию преодоления данных порогов достаточно для рассмотрения инициативы в государственных органах. Следует также учитывать тот факт, что эксперты при рассмотрении будут руководствоваться материалами инициативы, направленными официально, а не оперативными сведениями с ресурса. Инициатива, автором которой Вы являетесь, была передана в экспертную группу 12 августа 2013 года.

2) От лица оператора РОИ Фонда информационной демократии мы сделали все возможное, чтобы инициативы, получившие поддержку 100 000 граждан были незамедлительно направлены на рассмотрение экспертной группы. В соответствии с п. 24 Правил Указа Президента РФ N183 от 4 марта 2013 года, у экспертов есть 2 месяца для принятия решения. Заседание экспертной рабочей группы состоится уже в начале сентября 2013 года, а принятое решение будет оперативно опубликовано на сайте www.roi.ru.

3) О Вашем желании выступить на заседании экспертной рабочей группы по рассмотрению данной инициативы сообщено в аппарат Правительства РФ.

С уважением,
Президент Фонда информационной демократии
Массух И.И.

Итак.

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

По п.2 — скорее всего мой косяк, надо было адресатом указать в т.ч. и Михаила Абызова, как руководителя экспертной группы, которая будет рассматривать суть нашей петиции. В этом вопросе на самом деле и ФИД и РОИ и Массух лично мало что решает. И уже появились высказывания депутатов, что наша петиция с большой вероятностью будет рассмотрена в конце августа / начале сентября.

По п.3 — Ок! А вот это спасибо. Не обязательно имелось ввиду именно моё присутствие, но у данной петиции обязательно должен быть свой представитель(-ли) на заседании экспертной группы из состава тех людей, кто участвовал в подготовке и размещении текста петиции (РКС, ППР, АПИ).

По п.2 и 3 еще раз постараюсь связаться уже непосредственно с членами экспертной группы.

Кстати, вот её состав:
Абызов М.А. — Министр Российской Федерации (руководитель экспертной рабочей группы)
Бречалов А.В. — президент Общероссийской общественной организации малого и среднего предпринимательства «ОПОРА РОССИИ» (по согласованию)
Галушка А.С. — сопредседатель Общероссийской общественной организации «Деловая Россия» (по согласованию)
Гаттаров Р.У. — член Комитета Совета Федерации по науке, образованию, культуре и информационной политике (по согласованию)
Давыдов Л.В. — председатель Комиссии Общественной палаты Российской Федерации по региональному развитию и федеративным отношениям (по согласованию)
Дискин И.Е. — председатель Комиссии Общественной палаты Российской Федерации по развитию гражданского общества и взаимодействию с общественными палатами субъектов Российской Федерации (по согласованию)
Добрынин К.Э. — заместитель председателя Комитета Совета Федерации по конституционному законодательству, правовым и судебным вопросам, развитию гражданского общества (по согласованию)
Емельянов М.В. — первый заместитель председателя Комитета Государственной Думы по экономической политике, инновационному развитию и предпринимательству (по согласованию)
Железняк С.В. — заместитель Председателя Государственной Думы Федерального Собрания Российской Федерации (по согласованию)
Зубов И.Н. — статс-секретарь — заместитель Министра внутренних дел Российской Федерации
Иванов А.Ю. — заместитель Министра финансов Российской Федерации
Иванова С.В. — статс-секретарь — заместитель Министра регионального развития Российской Федерации
Ивлиев Г.П. — статс-секретарь — заместитель Министра культуры Российской Федерации
Катырин С.Н. — президент Торгово-промышленной палаты Российской Федерации (по согласованию)
Локоть А.Е. — член Комитета Государственной Думы по федеративному устройству и вопросам местного самоуправления (по согласованию)
Любимов Ю.С. — статс-секретарь — заместитель Министра юстиции Российской Федерации
Маковецкая С.Г. — директор Фонда «Центр гражданского анализа и независимых исследований „ГРАНИ“ (по согласованию)
Никитин Г.С. — заместитель Министра промышленности и торговли Российской Федерации
Нилов Я.Е. — председатель Комитета Государственной Думы по делам общественных объединений и религиозных организаций (по согласованию)
Ослон А.А. — президент Общероссийского общественного фонда „Общественное мнение“ (по согласованию)
Павлов И.Ю. — председатель совета Фонда „Институт Развития Свободы Информации“ (по согласованию)
Плигин В.Н. — председатель Комитета Государственной Думы по конституционному законодательству и государственному строительству (по согласованию)
Пономарев М.Н. — член Комитета Совета Федерации по конституционному законодательству, правовым и судебным вопросам, развитию гражданского общества (по согласованию)
Пудов А.Н. — статс-секретарь — заместитель Министра труда и социальной защиты Российской Федерации
Рапопорт Б.Я. — директор Департамента Правительства Российской Федерации по формированию системы „Открытое правительство“
Тополева-Солдунова Е.А. — председатель Комиссии Общественной палаты Российской Федерации по социальной политике, трудовым отношениям и качеству жизни граждан (по согласованию)
Третьяк Н.В. — статс-секретарь — заместитель Министра образования и науки Российской Федерации
Фомичев О.В. — статс-секретарь — заместитель Министра экономического развития Российской Федерации
Шлегель Р.А. — член Комитета Государственной Думы по информационной политике, информационным технологиям и связи (по согласованию)
Шохин А.Н. — президент Общероссийской общественной организации „Российский союз промышленников и предпринимателей“ (по согласованию)
Элькин Г.И. — руководитель Федерального агентства по техническому регулированию и метрологии
Яковлева Т.В. — заместитель Министра здравоохранения Российской Федерации
Яковлева Я.В. — председатель Некоммерческого партнерства содействия защите бизнеса „Бизнес Солидарность“ (по согласованию)
Ясин Е.Г. — научный руководитель федерального государственного автономного образовательного учреждения высшего профессионального образования „Национальный исследовательский университет “Высшая школа экономики»

Оригинал ответа на открытое письмо.
Оригинал Постановления Правительства РФ по утверждению состава экспертной рабочей группы.


Как вы считаете, мы, как поставившие свои подписи под петицией или поддерживающие её суть,…


Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 138 человек. Воздержалось 27 человек. Источник: habrahabr.ru,
получено с помощью rss-farm.ru




должны стоять на своём и требовать только отмены 187-ФЗ



можем допустить возможность приостановки действия 187-ФЗ с целью общественных обсуждений



можем согласиться на внесение отдельных изменений в 187-ФЗ, снижающих вред его воздействия на интернет, но при этом против его расширяющих дополнений



надо соглашаться на изменения, даже если ряд из них будет расширять область применения закона



ничего не поможет, я уверен в том, что петицию отклонят уже на стадии экспертной группы



я уверен в том, петицию отклонят на стадии рассмотрения Госдумы



другое мнение, обоснуйте

[recovery mode] Загадка A858

Суть: На reddit.com есть юзер A858DE45F56D9BC9, который постит в свой реддит (блог на reddit.com) куски бинарных данных. Продолжается это более 2 лет (с марта 2011). До сих пор не ясно кто и зачем это делает. Большинство данных до сих пор не декодировано.

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



Кто такой A858 и какой цели служит его блог?
Есть несколько теорий о цели блога:
  • Это игра/ARG.
    Если это игра, то, похоже, она не очень удалась. Большинство постов, как говорилось, все еще не расшифрованы, в тех же, что удалось расшифровать, не прослеживается никакой общей идеи. Впрочем, пока это выглядит как наиболее правдоподобное объяснение, так как декодированые посты показывают своеобразное чувство юмора автора.
  • Это Numbers station (Номерная радиостанция).
    Все бы хорошо, но расшифрованные посты не вписываются в эту теорию.
  • Команды для ботнета.
    Популярная теория, но как и в случае с номерной радиостанцией, не объясняет декодированых постов.
  • Хедхантинг специалистов по ИБ.
    Когда посты получали слишком много внимания, они удалялись. Если цель в привлечении специалистов по криптографии, то зачем это делать? К тому же, декодированые посты не были шифрованы в привычном смысле слова.
  • Серийные номера.
    Есть предположение, что это серийники товаров, сосканированые в магазине.

Что содержится в постах?
Большинство последних постов выглядит как случайные/шифрованные данные. Но некоторые ранние посты были декодированы, к примеру:
и тд.

Где можно посмотреть старые посты, после того как они удалены/изменены?
На этой странице — http://a858.soulsphere.org/.

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

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

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Continuous Integration для самых маленьких

Вы все еще публикуете проект вручную? Тогда мы идем к вам
Под катом гайдлайн по внедрению CI для .NET проектов «с нуля», включающий:
  1. Автоматические ежедневные сборки
  2. Уведомления о проблемах
  3. Интеграцию с баг-трекером и системой контроля версий
  4. Версионирование продукта
  5. Версионирование базы данных
  6. Автоматизированные выкладки и бекапы

Начнем с того, что же такое «непрерывная интеграция».
Непрерывная интеграция (англ. Continuous Integration) — это практика разработки программного обеспечения, которая заключается в выполнении частых автоматизированных сборок проекта для скорейшего выявления и решения интеграционных проблем.
С практической точки зрения это значит, что в любой момент времени у вас должна быть «живая актуальная версия продукта», которую можно протестировать или продемонстрировать.
Для этого нужно:
  1. Чтобы разработчики вносили свой код в VCS по крайней мере каждый день
  2. Сборка продукта происходила в автоматическом режиме
  3. Выкладка продукта (в том числе, обновление базы данных) происходила в автоматическом режиме
  4. Тестирование продукта происходило в автоматическом режиме (насколько это возможно)
Continuous Integration относится к agile-практикам. Agile предполагает итерационный процесс, с многократным повторением цикла разработки, тестирования и выкладки продукта. Автоматизация рутинных процессов позволяет избежать многократного выполнения рутинных операций.

Работа с VCSДля начала нам потребуется тестовое окружение для тестирования приложения. Если цикл тестирования достаточно длительный, а разработка ведется быстро, то разумно выделить еще и dev-окружение. Структура VCS будет отражать ваши окружения.
Все разработчики работают с основной веткой разработки, затем определенная версия фиксируется и мержится в тестовую ветку. Из тестовой ветки происходит выкладка на тестовое окружение. Производится тестирование, внесение фиксов и обратный мерж в дев. Протестированная версия отправляется в релизную ветку и от туда публикуется на продакшн. В случае нахождения ляпов на продакшне (к сожалению, такое бывает) чиним в авральном режиме из продакшн ветки и опять мержим в DEV-ветку.

В философии GIT будет немного иначе, так как при работе с GIT не принято комитить в master и даже dev. Вместо этого практикуется подход фича-бренч. Про git workflow можно почитать здесь: habrahabr.ru/post/60030/. Вообще, все предлагаемые структуры VCS преследуют одну цель: избежать ситуации, когда ветка разработки не стабильна, а совершенно необходимо что-то быстро «пофиксить» или «допилить» и выложиться. При выборе своей структуры задайте себе вопрос «смогу ли я выложиться на продакшн в течение одного дня и не поломать все. Если ответ «да», то структура вам подходит.

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

КонфигурацииКак бы мы не старались сделать окружения идентичными, конфигурационные файлы будут отличаться: тестовые и реальные аккаунты, токены, ID, внешние веб-сервисы и другое. .NET предлагает отличное средство поддержание конфигураций в актуальном виде: трансформации конфигов. Почему-то «из коробки» они включены только в веб-приложения. К счастью трансформации достаточно легко добавить и в другие приложения.
<code class="xml">  <UsingTask TaskName="TransformXml"
    AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
  <Target Name="AfterCompile" Condition="Exists('App.$(Configuration).config')">
    <!--Generate transformed app config in the intermediate directory-->
    <TransformXml Source="App.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config"
      Transform="App.$(Configuration).config" />
    <!--Force build process to use the transformed configuration file from now on.-->
    <ItemGroup>
      <AppConfigWithTargetPath Remove="App.config" />
      <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
        <TargetPath>$(TargetFileName).config</TargetPath>
      </AppConfigWithTargetPath>
    </ItemGroup>
  </Target>
</code>
Начинающие разработчики часто впадают в ступор при отладке трансформаций Web.config’а на локальных машинах: в отличие от App.config’ов они хранятся на уровне приложения, а не в папке bin, поэтому при локальной сборке трансформации не происходит. Трансформации применяются при публикации проекта. Если вам действительно нужно обойти это ограничение, можно создать файл Web.template.config и добавить трансформацию на PostBuild приложения. Не забудьте только убрать таск трансформации из проекта, иначе трансформация будет применяться дважды.
Если в приложении используют другие технологии, все-равно лучше иметь один основной конфигурационный файл с общими настройками и дополнительные конфигурационные файлы для изменения эталонного конфига. Это избавит вас от копипаста одинаковых настроек.

Версионирование продукта.NET предоставляет 2 атрибута для версионирования сборок
[assembly: AssemblyVersion(«1.0.0.0»)]
[assembly: AssemblyFileVersion(«1.0.0.0»)]
Первые две цифры – это мажорный и минорный номер версии. Эти цифры интерпретируют инкремент изменения функционала. Третья цифра – это, так называемый, номер сборки. Каждый день, пока версия находится в разработке эта версия увеличивается. И последний номер – это номер ревизии. Этот номер увеличивается каждый раз при сборке версии на билд-сервере в течение дня. Подробно о политике версионирования в .NET написано в книге CLR via C# Рихтера.
Автоматическое версионирование может быть настроено разными способами. Подробно эта тема обсуждается здесь: stackoverflow.com/questions/1126880/how-can-i-auto-increment-the-c-sharp-assembly-version-via-our-ci-platform-hudso.

Основные подходы

  1. Использование версии вида 1.0.*.* (плохо сочетается с билд-сервером)
  2. Использование единого файла SharedAssemblyInfo для управления версиями всех сборок из оного места (создается один файл с номером версии и добавляется “as a link” ко всем проектам
  3. Использование msbuild, вместо файла AssemblyInfo
  4. Для TFS можно использовать WWF-Activity
На мой взгляд удобнее всего использовать msbuild и проставлять значение с помощью CI-сервера:
<code class="xml"><Major>1</Major>
<Minor>0</Minor>
<Build>$(BUILD_NUMBER)</Build>
</code>
Все современные CI-решения предлагают такую переменную во время сборки. Для того, чтобы этот подход работал, нужно добавить импортировать msbuild-таски из msbuildtasks.tigris.org/ и добавить в конце проекта:
<code class="xml"><Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')" />
  <Target Name="BeforeBuild" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')">
    <Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)" />
    <AssemblyInfo CodeLanguage="CS" OutputFile="AssemblyFileInfo.cs" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" AssemblyConfiguration="$(Configuration)" Condition="$(Revision) != '' " />
  </Target>
</code>

Версионирование базы данныхЯ не знаю ни одного проекта, в котором не приходилось бы менять базу данных. .NET предлагает следующие решения:

SSDT-проект msdn.microsoft.com/ru-ru/data/tools.aspx

Плюсы: процесс создания и редактирования БД напоминает то, как бы вы это делали с Management Studio.
Минусы: сложность написания миграционных скриптов. Т.к. инкрементальные изменения строит сам проект, сохранность данных обеспечивается за счет pre-deploy и post-deploy-скриптов. Придется опираться на наличие/отсутствие полей в БД или «изобретать» таблицу schema version, уже реализованную в миграционных движках.

ECM7 Migrator code.google.com/p/ecm7migrator/

Движок миграций с открытым кодом. Проект поддерживает хабраюзер dima117.
Плюсы: поддерживаются разные СУБД, если что-то вас не устраивает, код открыт. Мигратор поддерживается и обрастает новыми функциями. И, пожалуй, самое важное, поддерживает несколько ключей миграций в одной базе данных. Это может быть очень полезно, если ваше приложение модульное и поддерживает плагины в том или ином виде. Каждый плагин может выполнять свои миграции и при этом использовать одну БД
Минусы: нет плюшек Entity Framework Migrations.

Entity Framework Migrations blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx

Плюсы: работает из коробки, автоматически создает миграции по Db-контексту, понимает команды из консоли visual studio, миграции публикуются с помощью стандартного Publish из Visual Studio.
Минусы: зависит от Entity Framework.


Я успел попробовать все 3 решения. Если вы используете EF, выбор – однозначно EF Migrations, для .NHibernate можно воспользоваться ECM7 Migrator. SSDT-проект подойдет любителям визардов и окошек.

Автоматизация публикации приложенияВ 2012 студии система публикации web-проектов была значительно улучшена. В первую очередь это касается профилей публикации. Если вы публикуете приложение в azure, то профиль можно просто скачать с портала. В противном случае его нужно будет создать.




Как видно на скриншотах, в последней версии WebDeploy можно запустить EF-миграции с помощью всего одной галочки. Кроме этого публикация из студии умеет заменять строку подключения без использования трансформации.
Подробно про трансформации и публикации написано у Троя Ханта в статье: www.troyhunt.com/2010/11/you-deploying-it-wrong-teamcity.html. Сейчас нас интересует пятый шаг его гайдлайна, а именно, автоматическая публикация с помощью билд-сервера: www.troyhunt.com/2010/11/you-deploying-it-wrong-teamcity_26.html. Я большой фанат TeamCity, поэтому рассмотрим именно эту CI.

Автоматизация публикации Windows-службДля автоматического создания windows-служб проще всего воспользоваться командной sc:
<code class="xml">sc [<ServerName>] creat|stop|start <ServiceName> binpath= <BinPath> start= demand
</code>
Единственный тонкий момент – каким образом доставить бинарники в <BinPath>. Это можно сделать разными способами: залить по FTP, воспользоваться PowerShell, использовать xcopy/robocopy или rsync в расшаренную папку на сервере. Выбор зависит от вашего сетевого окружения и требований к безопасности.

TeamCityИспользование средств, описанных выше, сэкономит ваше время. Пойдем дальше и установим билд-сервер. Скачиваем TeamCity: www.jetbrains.com/teamcity/ и запускаем инсталятор, жмем везде «Ок».
Два основных понятия TeamCity – «проект» и «билд». «Проект» соответствует вашему солюшну, а под билдом понимается любая осмысленная совокупность действий над вашим проектом: будь то сборка, запуск тестов, выкладка на сервер, создание бекапов и так далее.

Автоматизированная выкладкаПервым шагом, дадим возможность выкладывать новую версию тему у кого Visual Studio не устновлена.
Основная идея, это запустить msbuild-шаг с дополнительными параметрами, создайте новый Build Definition и выберите первый шаг Msbuild. В параметры командной строки нужно передать:
<code class="xml">/P:Configuration=%env.Configuration%
/P:DeployOnBuild=True
/P:DeployTarget=MSDeployPublish
/P:MsDeployServiceUrl=https://%env.TargetServer%/MsDeploy.axd
/P:AllowUntrustedCertificate=True
/P:MSDeployPublishMethod=WMSvc
/P:CreatePackageOnPublish=True
/P:UserName=AutoDeploy\Administrator
/P:Password=Passw0rd
</code>
Эти параметры укажут, куда нужно публиковать.
Для того, чтобы опубликовать миграции потребуется дополнительный шаг Command Line:
<code class="xml">SET AssemblyName=MyMvc4App
SET StartUpDirectory=MyMvc4App\bin\
SET ConnectionString=Server=tcp:XXXX.database.windows.net,1433;Database=XXXX;User ID=XXXX;Password=XXXX;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;MultipleActiveResultSets=True
SET ConnectionStringProvider=System.Data.SqlClient
SET ConfigFilePath=%CD%\MyMvc4App\web.config
SET MigrateExe=packages\EntityFramework.5.0.0\tools\migrate.exe
%MigrateExe% %AssemblyName%.dll /startUpDirectory:%StartUpDirectory% /startUpConfigurationFile:"%ConfigFilePath%" /connectionProviderName:"%ConnectionStringProvider%" /connectionString:"%ConnectionString%" /verbose
</code>
Сохраняете билд. Теперь кто угодно может опубликовать последнюю версию из VCS. Хорошая практика публиковаться на дев-стенд каждый день до начала рабочего дня. Таким образом вы будете отлавливать интеграционные проблемы максимально быстро.

Rolling buildsЕще одна хорошая практика – настроить триггер на запук билда, который просто будет запускать сборку вашего солюшна после каждого изменения в репо или по таймеру (например, каждые 10 минут), если над проектом работает одновременно очень много разработчиков. К этому билду следует подключить нотификацию. TeamCity поддерживает нотификации по почте, jabber, с помощью плагина для VisualStudio и Tray-приложения. Выберите вариант по вкусу. Мне по душе приложение в трее. Если билд сломался – надо срочно чинить.

Как не ломать билдКакие бы практики вы не вводили, чтобы не делали, не существует никакого способа дать 100% гарантию, что разработчики не будут вносить в VCS код, который даже не собирается. Этот вопрос должен решаться с помощью административных мер: не уходить с работы, не проверив, что билд после твоих изменений собрался, кто сломал, тот и чинит. В одной компании, где я работал проблема со слишком часто сломанным билдом была решена правилом: сломал билд – принеси тортик. Сначала торты ели каждый день, потом перестали.

Автоматический запуск тестовЭтот шаг следует разделить на 2: юнит-тесты и интеграционные и приемочные тесты. Это важно, потому что юнит-тесты должны работать на любом окружении. Все внешние зависимости заменяются фейками.

Запуск юнит-тестов

Здесь все просто. Выбирайте Build Step “Nunit” или “MsTest”, вводите паттерн **.Test*.dll все остальное TeamCity сделает за вас, при условии, что вы используете паттерн .Tests в названии ваших тестовых проектов.

Запуск интеграционных и приемочных тестов

Эти тесты могут зависеть от многих факторов и их запуск может предполагать накатывание бекапов или скриптов инициализации. Возможно, что вы захотите построить дополнительные отчеты о запуске таких тестов. Лучше не захламлять ваш проект с выкладкой и создать для них специальный билд. TeamCity позволяет создавать цепочки билдов. В Build triggers билда с приемочными/интеграционными тестами вы можете добавить триггер, срабатывающий при удачном прохождении билда с выкладкой. Создание такого билда для запуска приемочных тестов я описал в топике: habrahabr.ru/post/182032/.

БекапыСоздание бекапов при выкладке также может быть автоматизировано. Для бекапа файловой системы, лично я не нашел ничего лучше, чем nnbackup: www.nncron.ru/index_ru.shtml.
<code class="xml">nnbackup -n 10 verz -i <Src> -o <Destination> -s -e –v
</code>
Команда создает аривирует в zip папку source и копирует архив в destination. Устанавливать nnbackup на целевые машины или вызывать с билд-сервера: вопрос ваших предпочтений, расположения билд сервера, сетевых издержек и безопасности.

Бекапить sql-сервер можно с помощью T-SQL
<code class="xml">BACKUP DATABASE AdventureWorks2012 TO DISK='X:\SQLServerBackups\AdventureWorks1.bak', DISK='Y:\SQLServerBackups\AdventureWorks2.bak', DISK='Z:\SQLServerBackups\AdventureWorks3.bak' WITH FORMAT, MEDIANAME = 'AdventureWorksStripedSet0', MEDIADESCRIPTION = 'Striped media set for AdventureWorks2012 database; GO
RESTORE DATABASE AdventureWorks FROM DISK='$(Backup)'
</code>
Т.е. для автоматического бекапа, вам потребуется добавить еще один Command Line-шаг. Или вы можете воспользоваться msbuild-тасками из того-же самого community-пакета, а для nnbackup написать свой msbuild-таск.
Можно пойти дальше и поставить триггер на запуск автоматического отката из бекапа, если приемочные тесты не прошли. Тогда у вас будет цепочка билдов: Выкладка » Приемочные тесты » Откат из бекапа.

Интеграция с системой ведение проекта и баг-трекеромДо этого момента, мы уже сделали много полезного. Осталась одна неприятная особенность. Билд-сервер все-еще никак не связан с нашим процессом разработки. Он ничего не знает о задачах текущей итерации разработки.
TeamCity поддерживает интеграцию с YouTrack, Jira и Bugzilla. Интеграция выполняется буквально в 2 клика. После этого, указывая номер задачи в комментарии к комиту, вы увидите ссылки на соответствующие задачи в информации о билде.
YouTrack поддерживает обратную интеграцию. Основное преимущество: YouTrack будет автоматически указывать номер билда, в котором баг или фича были закрыты.

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

Артефакт – это любой файл, являющийся значимым результатом выполнения билда. Для билдов с инсталляторами вы можете указать my-installer.exe или my-package.zip, как маску для артефактов билда и TeamCity отобразит их в соответствующей вкладке.
Вот здесь и пригодится интеграция с Issue Tracker’ом. Тестировщик или менеджер может посмотреть закрытую задачу, перейти по ссылке с билдом и забрать версию с исправлениями из артефактов билда.

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

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Getty отдаёт 4600 изображений в общественное достояние



Музей J. Paul Getty открыл часть своей коллекции и передал её в общественное достояние. В рамках программы Open Content Program почти 4600 изображений высокого разрешения полностью освобождены от исключительных прав на интеллектуальную собственность. Кто угодно может использовать их без всяких ограничений, например, в качестве иллюстраций в Википедии.

Среди изображений в общественном достоянии, например, отсканированные копии некоторых картин Винсента ван Гога. Конечно, копирайт на сами картины давно истёк, но до сих пор отсканированных изображений такого качества в онлайне не было.

Многие из освобождённых картин имеют размер более 100 мегабайт.


«Ирисы», Винсент ван Гог, 1889, скачать (28 МБ)

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


Фотограф: Роджер Фентон (Roger Fenton), 1854-1858


Картина Клода Моне «Снежное утро» (Snow Effect, Morning), Франция, 1891


Неизвестный фотограф, кратер на Луне, фото 1850-х гг (вторая половина), изображение высокого разрешения


Недостроенная Эйфелева башня. Фотограф: Луи-Эмиль Дюрандель (Louis-Emile Durandelle), 23 ноября 1888 г.


Человек на воздушном шаре. Фотограф: Гаспар Феликс Турнашон (Gaspard Felix Tournachon), около 1863 г.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


3D сканер от MakerBot поступит в продажу уже на следующей неделе



Компания MakerBot достаточно известна на рынке 3D печати. Ее принтер Replicator стал популярным очень быстро, вследствие не очень высокой цены и относительно простой эксплуатации. Кроме того, компания не так давно сообщила о намерении выпустить на рынок и 3D сканер, при помощи которого можно было бы получать модель небольшого реального объекта, и эту же модель отправлять на 3D-принтер, для создания копии (не такой качественной, как оригинал, может быть, но тем не менее). И теперь этот сканер готов, и будет представлен на следующей неделе.

Сканер получил название Digitizer, изображен он на анонсной фотографии. Как и говорилось выше, Digitizer позволяет отсканировать объемный объект, получить компьютерную модель (CAD), и при необходимости отправить файл на «печать». Пока что о модели высокого разрешения и речи не идет. Но то, что получается в результате, вполне заслуживает похвалы разработчикам. Ниже показан оригинальный объект, его модель, и копия объекта, отпечатанная на принтере.



Стоит отметить, что ПО сканера позволяет исправлять погрешности изображения, используя цифровую«магию».



Все это — результаты работы команды MakerBot, и результаты эти, как видим, неплохие. К слову, модель можно распечатывать в разном масштабе. В качестве примера показаны сережки, «напечатанные» на 3D-принтере, в качестве модели для них служила фигурка сиамской кошки.



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

Кстати, вот видео работы прототипа устройства, показанного на мартовской конференции MakerBot:


Via MakerBot

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Используете ли вы оператор нестрогого сравнения (&quot;==&quot;) в PHP?

Из-за того, что в при сравнении строк оператор "==" пытается сначала преобразовать их в числа [1][2] (даже, если оба операнда — строки), результат порой может оказаться неожиданным:
<code class="php"><?php
var_dump('123' == '       123'); // true
var_dump('1e3' == '1000'); // true
var_dump('+74951112233' == '74951112233'); // true
var_dump('00000020' == '0000000000000000020'); // true
var_dump('0X1D' == '29E0'); // true
var_dump('0xafebac' == '11529132'); // true
var_dump('0xafebac' == '0XAFEBAC'); // true
var_dump('0xeb' == '+235e-0'); // true
var_dump('0.235' == '+.235'); // true
var_dump('0.2e-10' == '2.0E-11'); // true
var_dump('61529519452809720693702583126814' == '61529519452809720000000000000000'); // true в php < 5.4.4
</code>
Подобное сравнение также используется и в некоторых функциях. Например, в in_array:
<code class="php"><?php
$_GET['fileId'] = '0X1D';
// ...
$privateFileIds = array('29E0');
if (in_array(@$_GET['fileId'], $privateFileIds))
{
	print 'Access deny';
	exit;
}

// Выведет "Access deny", т.к. параметр "$strict" у функции "in_array" по умолчанию равен "false"
</code>
Решением проблемы может служить использование строгой проверки на соответствие:
<code class="php">// Использование оператора идентичности совместно с явным приведением операндов к строковому типу
(string) $aaa === (string) $bbb;

// Использование функции "strcmp"
strcmp($aaa, $bbb) === 0;

// Использование параметра "$strict" со значением "true" в соответствующих функциях
in_array((string) $aaa, $array, true);
</code>
Под строгой проверкой здесь подразумевается сравнение операндов одного типа исключительно по правилам сравнения данного типа.

UPD: пользователь v0s подсказывает, что проверять результат функции "strcmp" с помощью оператора "==" небезопасно (поэтому для проверки используйте оператор "===").


Используете ли вы для сравнения строк нестрогую проверку на соответствие (оператор "==", параметр "$strict" со значением false и т.п.)?


Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 1258 человек. Воздержалось 292 человека. Источник: habrahabr.ru,
получено с помощью rss-farm.ru




да, использую, о подводных камнях не знал



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



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



нет, всегда и во всех случаях для сравнения строк использую только строгую проверку на соответствие (оператор "===" с ручным приведением типов, функцию "strcmp", параметр "$strict" с ручным приведением типов и т.п.)

Perl6 — Обработка исключений

1. Особенности работы с переменными и литералами в Perl6
2. Perl6 — Операции над переменными, анонимные блоки
3. Perl6 — Условные операторы, циклы
4. Perl6 — Работа с функциями
5. Perl6 — Классы
6. Perl6 — Ввод-вывод,
7. Perl6 — Комментарии, пробельные символы, скобки
8. Perl6 — Перегрузка операторов
9. Perl6 — Работа с типами данных
В прошлой статье я заикнулся об отлове исключений. Немногие скрипты, что встречались с исключениями, выживали, и слишком много моих скриптов погибло от их рук. Пожалуй, настало время устроить на них охоту. Для тех кому интересно, чем же мы будет их ловить — встречаемся под катом.


И так, имеем следующий кусок кода:
<code>sub Func($a)
{
   my $temp =  $a*2;
}

Func "Test";
</code>

Как вы уже могли догадаться, мы получим исключение при попытке получить из строки «Test» десятичное число.
Чтобы добавить обработчика исключений мы должны добавить следующую конструкцию:
<code>sub Func($a)
{
   my $temp = $a*2;
   say "Test work";

   CATCH
   {
      default
      {
          say "Something is wrong!";
      }
   }
}

Func "Test";
say "Another test work";
</code>

В отличии от того же с++, в шестом перле блок обработки исключений добавляется внутрь того блока, где может произойти исключение. Таким образом, при выполнении данного скрипта мы получим вывод:
<code>Something is wrong!
Another test work
</code>
Иначе говоря, блок, в котором происходит исключение останавливает свою работу (и всетаки немного неправильно так говорить, но об этом поговорим потом), и начинается работа блока CATCH, в которой производится вывод строки Something is wrong. После выполнения блока CATCH скрипт продолжает выполнение начиная со следующей команды, идущей за блоком, в котором произошло исключение. Именно поэтому мы не видим на экране надписи «Test work».

Фактически, наш блок CATCH является обычным «свитчем» И мы можем добавить следующее:
<code>sub Func($a)
{
   my $temp = $a*2;
   say "Test work";

   CATCH
   {
      when X::Syntax::Name::Null
      {
          say "I will never say it =(";
      }
      default
      {
          say "Something is wrong! "~$_.WHAT.gist;
      }
   }
}

Func "Test";
say "Another test work";
</code>
Однако текст для выбранного нами исключения гласит «Я никогда не скажу этого». Это потому что в нашем случае в функции не выполняется таких действий, в которых бы возникло данное исключение. Чтобы всетаки понять какое же исключение нам попадается, я добавил
"$_.WHAT.gist"
. При входе в блок CATCH в переменную $_ заносится пойманный нами объект исключения. Потом мы берем его type object'а и приводим его к строке (.gist функция для дебага, позволяющая посмотреть внутренности объекта, описывать её здесь не буду).
Таким образом мы теперь получаем такой вывод:
<code>Something is wrong! (X::Str::Numeric)
Another test work
</code>
Теперь мы знаем какое именно исключение словили. Копируем его имя и идем смотреть в Синопсах описание нашего исключения. (Вот прямая ссылка на неше исключение). После чего мы можем добавить ещё один блок when:
<code>sub Func($a)
{
   my $temp = $a*2;
   say "Test work";

   CATCH
   {
      when X::Syntax::Name::Null
      {
          say "I will never say it =(";
      }
      when X::Str::Numeric
      {
          say "String convertation error!";
      }
      default
      {
          say "Something is wrong! "~$_.WHAT.gist;
      }
   }
}

Func "Test";
say "Another test work";
</code>

В результате чего увидем вывод:
<code>String convertation error!
Another test work
</code>

Естественно мы можем через переменную $_ обращаться ко всем полям объекта. Поля опять же смотрим в описании исключения.

-Уфф, что-то я устал охотиться, может ловушек поставим, да передохнём?
Есть так же специальный блок try {}, внутри которого есть «невидимый» блок CATCH, и если внутри этого блока произойдет исключение, то работа скрипта не остановится, и выполнение продолжится со следующей инструкции после этого самого блока. Таким образом можно просто игнорировать все исключения которые нам попадутся.

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

-А если попытается сбежать?
Вполне возможен вариант, что во время обработки одного исключения мы можем получить ещё одно. Однако стоит отметить, что блок when или default, в котором происходит обработка являются самыми обычными блоками, внутрь которых опять же можно поместить блок CATCH:
<code>sub Func($a)
{
   try
   {
      my $temp = $a*2;
      say "Test work";

      CATCH
      {
         when X::Str::Numeric
         {
             die "test";
             CATCH
             {
                default
                {
                   say "Another die action";
                }
             }
         }
         default
         {
             say "Something is wrong! "~$_.WHAT.gist;
         }
      }
   }
}

Func "Test";
say "Another test work";
</code>

-А давай попытаемся приручить парочку исключений?
Пожалуй у нас найдется парачка способов, как можно самостоятельно создать исключение:

Первый способ это как вы уже заметили оператор 'die':
<code>{
   die "I'm diying...";
   CATCH
   {
      default
      {
         say "I will save you!";
      }
   }
}
</code>

Второй способ — это вызов метода throw:
<code>{
   X::Str::Numeric.throw;
   CATCH
   {
      default
      {
         say "More exception!?!";
      }
   }
}
</code>

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

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

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Google упал на две минуты — объем мирового трафика сократился на 40%

Вчера в 03.51 по московскому времени все службы Google, в том числе и поиск, ушли в оффлайн на 1-5 минут. Это хорошо видно в сервисе мониторинга Apps Status Dashboard. Казалось бы, ничего страшного — всего около двух минут. Однако такое событие не могло не отразиться на других сайтах Интернета.

Сервис сбора данных со счетчиков GoSquared зафиксировал общее посещаемости сайтов в интернете на 40%. На графике наглядно видно резкое падение и затем скачок трафика:

image

В момент отключения Google в России была глубокая ночь, поэтому событие осталось незамеченным. Но в США был конец рабочего дня, реакция пользователей была незамедлительна — Twitter быстро наполнился сообщениями вроде «Google не работает, можно идти домой!».

Google до сих пор еще не прокомментировал отключение своих служб на несколько минут. По подсчетам экспертов это событие стоило корпорации более $500 тыс.

Такие результаты всего лишь двухминутного отключения заставляют задуматься: а что, если оно продлится Час? День? Неделю?

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Автоматизация сборки .NET приложений — часть 2



Три года назад я писал статью про автоматизацию сборки .NET приложений. Планировалось, что она будет из двух частей. Первая часть — основы использования NAnt и примеры выполнения базовых задач (компиляция проекта, сборка сайта ASP.NET). Во второй части хотел рассказать о более продвинутых задачах типа трансформации конфигов, запуска модульных тестов и т.п.

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

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


Написание собственных тасков
Таск (task) — это элемент билд-скрипта, который выполняет определенное действие (например, копирует файл в другую папку или запускает модульные тесты). Таск может содержать параметры. Например, таск regasm регистрирует COM-объекты из заданной библиотеки, а его параметром является путь к нужному файлу .dll.

<code class="xml"><regasm assembly="myAssembly.dll" />
</code>
NAnt уже содержит большое количество тасков для решения разнообразных задач, но, к сожалению, иногда их не хватает. В этом случае, вы можете написать собственные таски, выполняющие нужные действия и использовать их в своих билд-скриптах. Сделать это очень легко!

Каждый таск — это класс .NET, унаследованный от базового класса
NAnt.Core.Task
(из библиотеки
NAnt.Core.dll
). Для написания собственного таска открываем Visual Studio, создаем новый проект
Class Library
, добавляем ссылку на
NAnt.Core.dll
и создаем примерно такой класс:

<code>[TaskName("my-task")]
public class MyTask : NAnt.Core.Task
{
	protected override void ExecuteTask()
	{
		// TODO: здесь выполняются нужные действия
		System.IO.File.WriteAllText("file.txt", "Hello, world!");
	}
}
</code>
NAnt.Core.Task
— абстрактный класс, все наследники которого должны содержать собственную реализацию абстрактного метода
void ExecuteTask()
— именно в нем и выполняются те действия, для которых предназначен таск. Для того, чтобы задать имя XML-тэга, которое будет потом использоваться в билд-скриптах, нужно пометить созданный класс атрибутом
TaskName
.

Для передачи параметров добавьте в класс свойства и отметьте их атрибутом
TaskAttribute
. Во время выполнения в этих свойствах будут находиться значения, указанные в параметрах таска в билд-скрипте.
Обратите внимание, для передачи в параметрах пути к файлам удобнее использовать свойства типа
System.IO.FileInfo
, а не
string
.

<code>[TaskAttribute("path", Required = true)]
public string Path { get; set; }
</code>
Для записи сообщений в лог используйте метод
Log
из базового класса.

<code>Log(Level.Warning, "Файл не найден");
</code>

Использование и отладка собственных тасков
Для использования в билд-скрипте собственных тасков нужно подключить свою скомпилированную библиотеку при помощи команды
loadtasks
, а потом вызвать нужные таски, используя имя, заданное в атрибуте
TaskName
.

<code class="xml"><loadtasks assembly="MyLibrary.dll" />
<my-task path="D:\temp" />
</code>
Для отладки своего таска добавьте в нужное меcто вызов статического метода
System.Diagnostics.Debugger.Launch()
и соберите библиотеку в режиме Debug. При запуске таска через NAnt в указанном месте выполнение скрипта остановится и вам будет предложено запустить для отладки Visual Studio.

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

Создание новой базы данных MSSQL
<code class="xml"><createDatabase database="dbname" instance="." integratedSecurity="true" />
</code>
Бэкап базы данных MSSQL
<code class="xml"><!-- integrated security -->
<backupDatabase database="dbname" instance="." integratedSecurity="true" backupFileName="d:\test.bak" />
<!-- user & password -->
<backupDatabase database="dbname" instance="." user="sa" password="123" backupFileName="d:\test.bak" />
</code>
Добавление пользователям MSSQL прав на базу данных (пользователям добавляется роль db_owner; если пользователи не существуют, они создаются)
<code class="xml"><addDatabaseUsers database="dbname" instance="." integratedSecurity="true">
	<user login="IIS APPPOOL\test" isWindowsUser="true" />
	<user login="test1" password="123" />
	<user login="test2" password="qwert" />
</addDatabaseUsers>
</code>
Минификация JS и CSS (использует YUI Compressor for .NET):
<code class="xml"><minify-js obfuscate-js="true" with-line-breaks="true" disable-optimizations="true">
	<files>
		<include name="test2.js" />
		<include name="test.js" />
	</files>
</minify-js>

<minify-css compression-type="hybrid" with-line-breaks="true">
	<files>
		<include name="*.css" />
	</files>		
</minify-css>
</code>
Компиляция .LESS файлов (используется DotLess):
<code class="xml"><compile-less file="D:\projects\ecm7milk\milk.less" result="D:\milk.min.css" />
</code>
Создание сайта в IIS
<code class="xml"><createIISWebSite websiteName="xxx3.ru" fileSystemPath="d:\xxx3.ru" appPool="xxx3.ru">
	<bindings>
		<add host="localhost" port="4898" protocol="http" />
		<add host="xxx3.ru" />
	</bindings>
</createIISWebSite>
</code>
Создание application и виртуальных каталогов в IIS
<code class="xml"><createIISApplication websiteName="xxx3.ru" virtualPath="/admin" fileSystemPath="d:/admin" />
<createIISDirectory websiteName="xxx3.ru" applicationVirtualPath="/admin" virtualPath="/images" fileSystemPath="d:/images" />
</code>
XDT-трансформация XML-файлов
<code class="xml"><xdt target="test.xml">
	<transformation>
		<moo1 xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
			<moo2 xdt:Transform="Insert">123</moo2>
			<rewrite xdt:Transform="Insert">
				<a1>456!</a1>
			</rewrite>
		</moo1>
	</transformation>
</xdt>
</code>
XDT-трансформация XML-файлов (параметры трансформации вынесены отдельно)
<code class="xml"><!-- в другое место билд-скрипта  -->
<xdt target="test.xml">
	<transformation refid="mimimi" />
</xdt>
...
<raw-xml id="mimimi">
	<moo1 xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
		<moo2 xdt:Transform="Insert">123!</moo2>
		<rewrite xdt:Transform="Insert" xxx2="${test.property}" aaa="bbbb">
			<a1 xxx1="${test.property}">456!</a1>
		</rewrite>
	</moo1>
</raw-xml>

<!-- в отдельный файл  -->
<xdt target="test.xml">
	<transformation file="transform.xml" />
</xdt>
</code>
Обратите внимание, внутри файлов с описанием трансформации можно использовать выражения NAnt.

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

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Ratpack — талантливо перепето

Исторически сложилось, что Groovy берет много хорошего у Ruby. В первую очередь, конечно Grails (от Rails), но и Spock (от Spec) и даже где-то Gradle (от Buildr, хотя никто не признается). Сегодня я вам расскажу про еще одну толковую «спертую» штуку — web framework Ratpack.
image
Списан Ratpack с Sinatra, о котором много написано на Хабре, например вот тут.
На мой взгляд, главное преимущество Синатры — что он талантливый певец что это простейший в использовании и моментальный в разработке фреймворк. Создать несколько простых страниц, менять их и видеть результаты налету, и за несколько часов сваять достаточно нетривиальный сайт с динамическим контентом — это как раз то, для чего и был придуман Синатра. Это, своего рода, ответ «ожиревшим» Рельсам. Точно в такой же роли (ответа «ожиревшим» Грейлзам) Синатра и перекочевал в Груви.

Должен заметить, что на сей раз сообщество Груви были не первыми, кто передрал Синатру. Первыми были Scala, со своей Скалатрой (ага, ответ на «ожиревший» Play). Насколько я знаю, решение не делать название похожим на слух, а искать ассоциацию по смыслу, было принято в первую очередь, придя в ужас от звучания названия версии Скалы :)

Ratpack переводится на русский как Крысиная стая, и привязка к Синатре в том, что это тусовка, в которой тусовался Франк Синатра.

А причем тут Java?
Ну, тут, мне кажется, все ясно. В отличие от Руби, где когда-то был lightweight RoR, или от Груви с его Грейлз, в Джаве никогда не было «легковесных» фреймворков. У нас есть либо громоздкие server-side component фреймворки типа JSF и Wicket, либо MVC фреймворки, которые, конечно, легче компонентных монстров, но все равно, требуют нагородить MVC для простейшей странички. Тут, конечно, я говорю о Spring MVC и Struts2. И всё это с жутко медленным циклом разработки «поменял слово? перезагрузи!». Бррр.

Как всегда, преимущество Груви для програмистов Джава — что они чувствуют себя как дома. 99% Java кода работает в Грувях без изменений, поэтому любой Груви фреймворк или инструмент может быть немедленно использован Java программистом.
Ситуация и с ratpack еще лучше — разработчики специально постарались, чтобы можно было писать на чистой Джаве, не задействуя Груви ни на одном этапе разработки. Один из примеров в этой статье будет написан 100% на Java. Кого не интерсует всё это Грувийное шаманство, перекручивает прямо на последний пример. Остальные начинают здесь:

Hello, World!
Ну, я думаю, начать надо с Hello, World!, правда? Полноценное веб-приложение на ratpack выглядит так:
<code>@GrabResolver('http://oss.jfrog.org/artifactory/libs-snapshot') //(1)
@Grab('org.ratpack-:ratpack-groovy:0.9.0-SNAPSHOT')
import static org.ratpackframework.groovy.RatpackScript.ratpack

ratpack { //(2)
    handlers {
        get {
            response.send 'Hello, world!' //(3)
        }
    }
}</code>
Всё. Честно. Пишем это в файл (например ratpack.groovy), запускаем через
groovy ratpack.groovy
:
INFO: Ratpack started for http://localhost:5050

Послушно идем на
http://localhost:5050
и обнаруживаем там ожидаемое:

Давайте посмотрим, что же мы написали:
  1. Это инструкция скачать все необходимые библиотеки с бесплатного opensource аккаунта Artifactory
  2. Это объявление приложения, оно состоит из обработчиков и модулей
  3. Это обработчик команды get. Поскольку у него нет параметров, он отработает по вызову root url. Тут-то мы и просим вернуть Hello World.
Добавляем еще один handler
Вписываем в наш ratpack.groovy еще один обработчик:
<code>ratpack {
    handlers {
        get {
            response.send 'Hello, world!'
        }
        get('habr'){
            response.send 'Hello, habr!' //наш новый обработчик
        }
    }
}
</code>
Файл сохраняем, в браузере идем на
http://localhost:5050/habr
, наслаждаемся.

Перезагружать? Нееее, это не для нас. Кто молодец? Spring-loaded молодец.
Добавим динамизьму
Прибавим скорости и интересу. Код:
<code>ratpack {
    handlers {
        get('hello/:username') {
            response.send "Hello, ${pathTokens.username}"
        }
    }
}</code>
Результат:

Ну, или так. Код:
<code>ratpack {
    handlers {
        get('hello') {
            response.send "Hello, ${request.queryParams.username}"
        }
    }
}
</code>
Результат:

Подключаем шаблоны
Можно упомянуть еще о многих интересных фичах, но статья уже и так не короткая, а я еще будет пример на чистой Джаве, поэтому давайте посмотрим на работу с шаблонами. Для примера возьмем Groovy template:
Шаблоны лежат в директории
templates
. Сохраним там, например,
index.html
со следующим содержанием:
<code class="html"><html>
<head>
    <title>${model.title}</title>
</head>
<body>
    <h5>${model.content}</h5>
    <br/>
    <img src="http://habr.habrastorage.org/post_images/9a5/14b/49a/9a514b49a2017e50f386f154c8cb0da2.png"/>
</body>
</html>
</code>
Скрипт с обработчиком теперь выглядит так:
<code>@GrabResolver('http://oss.jfrog.org/artifactory/libs-snapshot')
@Grab('org.ratpack-framework:ratpack-groovy:0.9.0-SNAPSHOT')
import static org.ratpackframework.groovy.RatpackScript.ratpack
import static org.ratpackframework.groovy.Template.groovyTemplate

ratpack {
    handlers {
        get {
            render groovyTemplate("index.html", title: 'Привет Хабру от Ratpack', content: 'Тут логотипы:')
        }
    }
}
</code>
Обратите внимание на новый static import.
Результат ожидаем:

Кто ждал Джавы? Их есть у нас!
Ну, тут не будет запускаемого скрипта, и не ждите. Тут будет серьезное приложение, со структурой директорий, модулями, с файлом сборки.
Dependency injection будет на Guice, веб-сервер на netty, сборка и запуск на gradle, перезагрузка с помощю Spring-loaded.
Поехали:
Структура проекта:

Файл ratpack.properties говорит кто есть
HandlerFactory
(откуда брать обработчиков):
<code class="java">handlerFactory=example.HandlerFactory
</code>
Класс
example.HandlerFactory
является, натурально factory для обработчиков. У нас там только один,
Hello, %username%
:
<code class="java">package example;

import ...

public class HandlerFactory implements org.ratpackframework.launch.HandlerFactory {

    public Handler create(LaunchConfig launchConfig) {
        return chain(new Action<Chain>() {
            public void execute(Chain chain) {
                chain.add(get("hello/:username", new Handler() {
                    public void handle(Context context) {
                        Map<String, String> pathTokens = context.getPathTokens();
                        context.getResponse().send("Hello from Java, " + pathTokens.get("username"));
                    }
                }));
            }
        });
    }
}
</code>
Да, Java 8 не помешал бы.
Тут все похоже на Грувийную версию — добавляем обработчик на путь hello/:username, потом берем значение динамической части пути из
context.getPathTokens()
.

Запускаем task-ом
run
, перекомпилируем изменения task-ом
classes 
(в другом окне,
run 
останавливать не надо):

Результат:


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

Заключение
Естественно, это самые основы, естественно, в Ratpack есть намного больше плюшек, чем я сейчас показал. Это и Guice-а, и , и интеграция с MongoDB и с GORM-ом.

Использование Java классов для обработчиков, модулей и сервисов дает возможность создавать модулярное и легко тестируемое приложение средней сложности.
Использование Groovy скриптов дает возможность гораздо более быстрой разработки чего-либо простого, «на коленке», с впечатляющими результатами.

Я надеюсь, что сумел заинтересовать вас этим фреймворком. Как вы могли заметить, даже первая версия еще пока не вышла (хотя уже скоро), поэтому я бы не стал переписывать на него mission-critical приложения, но он достоин того, что обратить на него внимание, и попробовать наваять на нем вашу следующую «жуткую домашнюю страничку»

P.S.
Если вы хотите продолжения, пишите в комменты.
Если вы хотите пообщаться на счет Ratpack-а лично, а так-же послушать про другие интересные штуки, приходите на JUG 31-го августа.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


[Перевод] Конвертируем HTML в PDF при помощи Dompdf


PDF — формат, ставший уже стандартом. Он был изначально создан Adobe для представления текста и изображений в документе с фиксированной структурой. Давно не редкость для веб-приложений, поддерживающих скачку данных, таких как счета или отчеты, отдавать их в PDF формате. Так что в этой статье мы пройдем простую генерацию PDF документов используя .

Dompdf — это отличная библиотека, способная генерировать PDF из HTML-разметки и CSS-стилей (в большинстве случаев это стили, совместимые с CSS 2.1 с поддержкой некоторых свойств CSS3). Мы можем определить, как наше содержимое должно выглядеть, используя эти знакомые технологии, и после легко конвертировать его в фиксированный документ. Также эта библиотека имеет и другие полезные и интересные функции.

Приступаем к работе

Dompdf доступен на GitHub и может быть установлен используя Composer. Установка через Composer без каких-либо ошибок часто вызывает трудности, поэтому я рекомендую просто использовать Git для установки Dompdf.

Библиотека требует PHP >= 5.0 с активированными расширениями mbstring и DOM. Также она требует несколько шрифтов, которые обычно доступны на большинстве компьютеров.

Перейдите в директорию, куда собираетесь установить библиотеку и выполните в командной строке:

<code class="bash">git clone https://github.com/dompdf/dompdf.git
git submodule init
git submodule update
</code>

Как только мы скачали Dompdf, давайте напишем короткий пример, который сгенерирует простой PDF документ:

<code class="php"><?php
set_include_path(get_include_path() . PATH_SEPARATOR . "/path/to/dompdf");

require_once "dompdf_config.inc.php";

$dompdf = new DOMPDF();

$html = <<<'ENDHTML'
<html>
 <body>
  <h1>Hello Dompdf</h1>
 </body>
</html>
ENDHTML;

$dompdf->load_html($html);
$dompdf->render();

$dompdf->stream("hello.pdf");
</code>

Для того, чтобы использовать библиотеку в проекте, мы сначала подтягиваем файл dompdf_config.inc.php, который содержит большую часть конфигурации Dompdf. Он также загружает autoloader и пользовательский файл конфигурации в котором мы можем переопределить параметры по умолчанию.

HTML-разметка передается как строка в метод load_html(). Альтернативно мы можем загрузить разметку из файла или URL, используя метод load_html_file(). Он принимает имя файла или URL веб-страницы в качестве аргумента.

Метод render() отображает HTML в PDF, и мы готовы к отдаче файла. Метод stream() отправляет результирующий PDF как вложение в браузер. Этот метод имеет необязательный второй параметр, массив опций:

  • Accept-Rangesboolean, отсылает заголовок “Accept-Ranges” (по умолчанию false).
  • Attachmentboolean, отсылает заголовок “Content-Disposition: attachment” заставляя браузер отображать запрос на сохранение (по умолчанию true).
  • compressboolean, включает сжатие содержимого (по умолчанию true).

Только что мы сгенерировали очень простой PDF, но это не совсем практично. В реальности мы часто имеем требования к размеру листа, ориентации страницы, кодировке символов и т.д. Есть целый набор опций, которые мы можем установить, чтобы сделать Dompdf более подходящим для наших реальных потребностей. Все они перечислены и объяснены в файле dompdf_config.inc.php, который устанавливает им значения по умолчанию. Вы можете менять эти значения, обновляя файл пользовательской конфигурации dompdf_config.custom.inc.php. Вот некоторые из важных настроек:

  • DOMPDF_DEFAULT_PAPER_SIZE – устанавливает размер листа по умолчанию для PDF-документа. Поддерживаемые размеры листов вы можете найти в файле include/cpdf_adapter.cls.php (значение по умолчанию — “letter”).
  • DOMPDF_TEMP_DIR – указывает временную папку, используемую Dompdf. Убедитесь, что эта директория доступна на запись согласно настройкам вашего веб-сервера.
  • DOMPDF_UNICODE_ENABLED – устанавливает, будет ли PDF использовать шрифты Unicode (по-умолчанию true).
  • DOMPDF_ENABLE_REMOTE – активирует включение изображений или CSS-стилей из удалённых сайтов (по-умолчанию false).
  • DEBUG_LAYOUT – устанавливает, будет ли отображена граница вокруг каждого HTML блока в PDF файле. Очень удобно для отладки макета (по умолчанию false).

Продвинутое использование

Теперь давайте немного поговорим о продвинутом использовании Dompdf. Возможно мы хотим сохранить сгенерированный PDF документ на диск, вместо того чтобы отсылать его в браузер. Вот как это делается:

<code class="php"><?php
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();

$output = $dompdf->output();
file_put_contents("/path/to/file.pdf", $output);
</code>

Вместо вызова stream(), как в прошлом примере, мы используем output(), который возвращает PDF как строку. Этот метод также принимает массив опций, но доступна лишь одна — compress (по умолчанию true).

Dompdf также позволяет нам добавлять хедер и футер к сгенерированному PDF, встраивая PHP-скрипт прямо в HTML, который он отображает. Но из-за того, что обработка произвольного кода может представлять из себя угрозу безопасности, значение конфигурации, которое отвечает за эту функциональность, по умолчанию выключено. Нам необходимо для начала установить опцию DOMPDF_ENABLE_PHP как true.

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

<code class="php">$html = <<<'ENDHTML'
<html>
 <body>
  <script type="text/php">
if (isset($pdf)) {
    // open the PDF object - all drawing commands will
    // now go to the object instead of the current page
    $footer = $pdf->open_object();

    // get height and width of page
    $w = $pdf->get_width();
    $h = $pdf->get_height();

    // get font
    $font = Font_Metrics::get_font("helvetica", "normal");
    $txtHeight = Font_Metrics::get_font_height($font, 8);

    // draw a line along the bottom
    $y = $h - 2 * $txtHeight - 24;
    $color = array(0, 0, 0);
    $pdf->line(16, $y, $w - 16, $y, $color, 1);
    
    // set page number on the left side
    $pdf->page_text(16, $y, "Page: {PAGE_NUM} of {PAGE_COUNT}", $font, 8, $color);
    // set additional text
    $text = "Dompdf is awesome";
    $width = Font_Metrics::get_text_width($text, $font, 8);
    $pdf->text($w - $width - 16, $y, $text, $font, 8);

    // close the object (stop capture)
    $pdf->close_object();

    // add the object to every page (can also specify
    // "odd" or "even")
    $pdf->add_object($footer, "all");
}
  </script>
  <h1>Hello Dompdf</h1>
 </body>
</html>
ENDHTML;
</code>

Скрипт встроен прямо в HTML-разметку и сначала открывает объект, чтобы мы могли влиять на отображение. Вся отрисовка будет записана в этот объект и мы сможем добавить его на все выделенные страницы (хотя есть и ограничения).

Затем мы получаем реальную ширину и высоту страницы, чтобы посчитать координаты футера, который мы собираемся добавить. Также нам требуется предоставить обьект шрифта, поскольку мы добавляем текстовое содержимое. Font_Metrics::get_font() позволяет создать объект, который нам необходим. Мы также берем высоту данного шрифта из его размера используя get_font_height(), чтобы посчитать позиционирование содержимого футера. Метод get_font_width() возвращает ширину нашего текста для данного шрифта и размера, которую мы также используем в наших вычислениях.

Метод line() рисует линию из точки (X1,Y1) в точку (X2,Y2). Обратите внимание, значение цвета подставляется не совсем в RGB. Основной PDF-класс требует значения между 0 и 1, так что мы конвертируем значения RGB в эти новые значения. Чтобы получить лучшее приближение (approximation), вы можете поделить их на 255.

Мы добавляем номер для каждой страницы, используя метод page_text(), которой принимает координаты X и Y, а также текст, который будет добавлен, объект шрифта, размер шрифта и цвет. Dompdf автоматически заменяет значения для {PAGE_NUM} и {PAGE_COUNT} на каждой странице, и делает $pdf доступным для нас.

Также мы можем не использовать встроенный PHP и достигать аналогичного эффекта прямо из PHP, примерно так:

<code class="php"><?php
$dompdf = new DOMPDF();
$dompdf->set_paper("A4");

// load the html content
$dompdf->load_html($html);
$dompdf->render();
$canvas = $dompdf->get_canvas();
$font = Font_Metrics::get_font("helvetica", "bold");
$canvas->page_text(16, 800, "Page: {PAGE_NUM} of {PAGE_COUNT}", $font, 8, array(0,0,0));
$dompdf->stream("sample.pdf",array("Attachment"=>0));
</code>

Обратите внимание, мы размещаем код после вызова $dompdf->render() потому что мы, по существу, редактируем уже созданный PDF.

Подведем итоги

В этой статье мы обсудили простой способ конвертировать HTML в PDF используя Dompdf. Несмотря на то, что Dompdf отличная библиотека, она не является полностью универсальным решением для генерации PDF документов; она все же имеет определенные ограничения и проблемы. Dompdf не очень терпимо относится к плохо оформленному HTML и большие таблицы могут легко привести к переполнению памяти. Некоторые базовые функции CSS, такие как float не полностью поддерживаются. И вообще, поддержка CSS3 очень ограничена. Если вам необходимы функции, которые не поддерживаются в Dompdf, вам может помочь к примеру wkhtmltopdf. Тем не менее, Dompdf является очень простым и удобным инструментом для решения большинства задач по экспорту PDF.

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

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Быстрый просмотр комментариев на Хабре

Похоже на этой неделе волна постов изменялок интерфейса Хабра. Напишу и про свою.

Иногда так бывает, что открываешь пост, а там уже сотни комментариев, а времени и желания читать всё нет, или тема не особо интересная чтобы тратить на неё много времени. Хочется посмотреть только самые интересные комментарии.

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

image



Слева от рейтинга может быть показана красная буква "A", что значит, что комментарий принадлежит автору, и синяя буква "i", что значит, что в комментарии есть картинка. Прозрачный светло-синий цвет фона говорит, что комментарий новый. Также в самом комментарии имя комментирующего подсвечивается красным, если он автор поста.

Скачать скрипт.

Установить скрипт можно через Greasemonkey в Firefox, и Tampermonkey в Chrome и Opera 15+. Чтобы иметь возможность поставить расширение в Опере надо сначала поставить расширение Download Chrome Extension. В Opera 12- можно установить через Violent monkey или стандартным способом.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Межзвездные путешествия: из пункта А в пункт Б



По космическим меркам человеческая раса весьма хрупкая и слабая: повышение температуры на 50 градусов, увеличение ионизирующего и ультрафиолетового излучения, отсутствие воды, уменьшение кислорода в атмосфере — все это ведет к ее неминуемой гибели. И нет ничего удивительного в том, что человеческий разум стал искать возможность существования других планет с благоприятными для нашей жизни условиями, дабы «развернуть» на них backup. Однако если планета и будет найдена, вопрос транспортировки остается открытым. В сегодняшнем посте речь пойдет о способах и перспективах межпланетных и межзвездных путешествий.



Имеющиеся сегодня в распоряжении человечества технологии не позволяют космическим кораблям достичь даже ближайшей звезды в течение одной человеческой жизни. Например, ближайшая к Солнцу звезда — Проксима Центавра — расположена на расстоянии 4,2 световых года. До Альфы Центавра (ближайшей к нам звездной системы, в которую входит и Проксима Центавра) 39 триллионов км. Современные космические корабли смогут преодолеть это расстояние за 70 тыс. лет. Становится понятно, что никто из людей не способен преодолеть такие расстояния. Отсюда и необходимость найти новый способ, чтобы отправиться в межзвездное путешествие.

Космические двигатели сегодня

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

Химические

Единственной проработанной технологией на сегодняшний день является ракетный двигатель. Его упрощенная схема такова:



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

Ядерные

Один из наиболее близко подобравшихся к реальности проектов в этой сфере – Orion, проект пилотируемого корабля для дальних космических миссий. В рамках проекта было создано два варианта: первый звездолет имел бы общую массу порядка 40 000 000 тонн и достигал бы Альфы Центавра за 1800 лет. Соответственно, задумывался он как «корабль поколений». Второй весил около 400 000 тонн и теоретически должен был добраться до точки назначения за 130 лет. Однако ограничение полезной нагрузки делало второй, более привлекательный вариант непригодным для пилотируемых перелетов.



Двигатель на антиматерии

Суть работы этого двигателя заключается во взаимодействии материи и антиматерии, после чего происходит мгновенная взаимная аннигиляция с выделением огромного количества энергии. Этой энергии хватит, чтобы достичь пункта Б. Но даже лучший из теоретически возможных двигателей, работающих на антиматерии, потребует около десяти железнодорожных цистерн топлива для разгона до крейсерской скорости и такое же его количество для торможения в точке назначения. И здесь возникает вопрос: а почему бы не работать с этой технологией? Ответ прост: стоимость производства одного грамма антиматерии будет стоить десятки миллиардов долларов. Кроме того, хранение антиматерии представляет собой нерешенную научную задачу, поскольку антиматерия не должна контактировать ни с одним атомом обычного вещества определенное количество времени, иначе произойдет взрыв.

Солнечный парус

Существуют идеи обеспечения движения космических кораблей, при котором топливо не используется. Их называют солнечным парусом (или световой парус, или фотонный парус). Излучаемые звездами фотоны способны оказывать давление на физические объекты. И если корабль оснастить большим, ультратонким и легким парусом, то давления солнечного света будет достаточно для его движения. Кроме того, на такой парус можно воздействовать и другими источниками излучения, например, сверхмощным лазером, размещенным на околоземной орбите, который будет постоянно направлен на корабль. Загвоздка заключается в том, что для движения шаттла необходим солнечный парус размером с Афганистан.



Проблемы путешествия

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

Тем не менее, физики-теоретики не опускают руки. Перемещение в пространстве со скоростью, превышающей скорость света, невозможно по причине того, что масса субъекта будет стремиться к бесконечности согласно формуле E=mc2. Однако в соответствии с теорией относительности скорость света является максимальной внутри пространства-времени; изменяя же само пространство-время, можно перемещаться с неограниченной скоростью. Например, расширение Вселенной может происходить со скоростью, намного превышающей скорость света, но при этом движение внутри самой Вселенной не может превысить скорость света.

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

Короткая дорога к звездам

Первый способ: через червоточины

Этот способ опирается на предположение, что в космосе есть «лазейки», существование которых обосновали Эйнштейн и Розен в 1935 году. Любителям фантастики эти лазейки известны под терминами «пространственно-временные тоннели», «червоточины», «кротовые норы» и так далее. Эти тоннели связывают между собой две точки в пространственно-временном континууме. Они позволяют перемещаться из точки А в точку Б.

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

Сама идея перемещения с помощью такого тоннеля привлекает физиков-теоретиков не только как способ добраться до звезд в течение жизни одного поколения, но и как научно-практическая уловка, позволяющая обойти теоретическую невозможность путешествия во времени. Конечно, пространственно-временной тоннель не может быть полноценной машиной времени, поскольку путешественник не может выбирать время, в котором он выйдет на другом конце тоннеля. Однако других возможностей наука пока не может предложить.
Как выглядят червоточины? Для человека и имеющихся в нашем распоряжении приборов они невидимы, поскольку не излучают ни в одном известном диапазоне. Но, допустим, человечество совершило одно из величайших открытий в истории фундаментальных наук и обнаружило вход в червоточину. Как его использовать? Увы, корабль из любых известных сегодня науке материалов теоретически не способен путешествовать по пространственно-временному тоннелю — предположительно, попадание такого объекта в червоточину приведет к ее схлопыванию. В 1988 году американский физик Кип Торн выдвинул гипотезу, что для путешествий через пространственно-временной тоннель необходима «экзотическая материя». Под столь легкомысленным названием физики подразумевают материю, обладающую «экзотическими» свойствами: так, предполагается, что роль стабилизатора тоннеля сможет выполнить материя с отрицательной массой им плотностью энергии.
Помимо оболочки, науке необходимо решить такую сложнейшую задачу, как предотвращение блокировки выхода из тоннеля, пока внутри него находится гипотетический корабль. Дело в том, что движущийся объект будет создавать внутри тоннеля гравитационную волну, искажающую пространство, что может привести к преждевременному закрытию выхода из тоннеля. А это означает, что все, что окажется в этот момент внутри него, просто исчезнет из нашей Вселенной.



Второй способ: в Пузыре Алькубьерре

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

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

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



Вывод

Чтобы в ближайшие 50-100 лет создать технологию межзвездных перелетов, лучшим ученым необходимо методично проводить научные изыскания, исследования и опытно-конструкторские работы над целым рядом вариантов двигательных установок. Дело в том, что и по сей день никто не может сказать, в каком направлении следует двигаться, чтобы создать «межзвездный» двигатель. Вполне возможно, что одно из представленных в данном обзоре направлений позволит человечеству снарядить экспедицию к звездам в ближайшее столетие.

Большинство технологий на сегодняшний день практически не приближены к технической реализации всех тех идей, которые выдвинуты физиками-теоретиками, потому в ближайшее время вряд ли удастся добраться до звезд, а особенно — с помощью «кротовых нор» или пузыря Алькубьерре.

Нелирическое отступление

Почему мы решили опубликовать этот пост в нашем блоге? Читая приветственные сообщения людей, которые приходят в Mail.Ru Group, замечаешь, что большинство из нас в той или иной форме интересуется будущим – перспективными технологиями, трендами, sci fi, наконец. Многие из нас обожают «Космическую одиссею» Кубрика, читают и до хрипоты обсуждают за обедом футурологические прогнозы, а некоторые и сами их составляют. Мы решили, что будет здорово рассказывать в блоге о будущем под разными углами и с разных точек зрения. Есть идеи для следующих постов? Мысли по поводу перспектив межзвездных путешествий? Ждем в комментариях!

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


[Перевод - recovery mode ] Google Research: Быстрое, точное выявление 100 000 категорий объектов на одной машине

Люди могут различать примерно 10 000 визуальных категорий высокого уровня, но мы можем различать гораздо больший спектр визуальных импульсов, называемых особыми признаками. Эти признаки могут соответствовать частям объекта, конечностям животного, архитектурным деталям, объектам на местности и другим зрительным образам, названия которых мы не знаем, но именно этот гораздо больший набор признаков мы используем в качестве основы для реконструкции и объяснения нашего ежедневного визуального опыта. Такие признаки обеспечивают компоненты для более сложных визуальных импульсов и создают контекст, который важен нам для разрешения неоднозначных композиций.

В отличие от нынешней практики компьютерного зрительного восприятия, пояснительный контекст, необходимый для решения визуальных деталей, может быть не только целиком и полностью местным. Мигающий быстрый красный прыгающий сигнал вдоль земли может быть детской игрушкой в контексте игровой площадки или петухом в контексте скотного двора. Было бы полезно иметь большое количество детекторов предметов, способных сигнализировать наличие таких предметов, включая детекторы для песочниц, качелей, горок, коров, кур, овец и сельскохозяйственных машин, необходимые для распознавания контекста с целью проведения разграничения между этими двумя возможными вариантами.
Лауреаты премии CVPR Best Paper Award (за лучший доклад по компьютерному зрению и распознаванию образов) этого года, в соавторстве с командой Googlers, куда входят Том Дин, Марк Рузон, Марк Сегал, Джонатан Шленс, Субхиндра Виджьянарасимхан и Джей Йягник, описывают технологию, которая позволит системе компьютерного зрения извлечь нужный тип семантически богатой контекстной информации, необходимой для распознавания визуальных категорий, даже если тщательного просмотра пикселей, покрывающих рассматриваемый объект, может быть недостаточно для их идентификации при отсутствии такой контекстной подсказки. В частности, рассмотрим основную операцию в машинном зрении, которая включает в себя определение уровня каждого конкретного местоположения объектов в изображении, где может присутствовать какой-либо конкретный объект.

Это так называемый оператор свертки, который является одним из ключевых элементов, используемых в машинном зрении и, более широко, в обработке всех сигналов. К сожалению, в вычислительном отношении, он дорог и, поэтому исследователи используют его экономно или пользуются экзотическим оборудованием SIMD, таким как графические процессоры и ПЛИС для уменьшения вычислительных затрат. Поставим всё с ног на голову, чтобы показать, как можно использовать быстрый табличный поиск – метод, называемый хешированием – для обмена времени на пространство, заменив вычислительно дорогой внутренний контур оператора свертки — последовательность операций умножения и сложения, необходимую для выполнения миллионов сверток, на один табличный поиск.

Мы демонстрируем преимущества нашего подхода путем масштабированного обнаружения объектов, доведя его из текущего состояния с привлечением нескольких сотен или, по большей мере, несколько тысяч категорий объектов до 100 000 категорий, что было бы эквивалентом более миллиона сверток. Кроме того, наша демонстрация была проведена на одном обычном компьютере, которому требуется всего лишь несколько секунд для каждого изображения. Основная технология используется в нескольких частях инфраструктуры Google и может быть применена к решению проблем вне компьютерного зрения, таких как обработка слуховых сигналов.

В среду, 26 июня, инженеры Google, ответственные за эти исследования, были награждены за лучший доклад на конференции IEEE по компьютерному зрению и распознаванию образов, которая состоялась в Портленде, штат Орегон.

Полный текст доклада можно найти здесь.

Цель публикации на Хабре: прочитать комментарии о перспективах технологий на базе данного исследования и их применения в рамках интернета.

P.S.
Это моя первая публикация на Хабре. Буду рад вашим замечаниям. И не судите строго.
Из-за нехватки кармы, нет возможности публиковать в хабах «Искусственный интеллект» и «Google».
Буду благодарен, если подскажите как перенести в указанные хабы.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


[Перевод] Python изнутри. Объекты. Начало

1. Введение.
2. Объекты. Начало

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

Как я и писал в предыдущем эпизоде (который, кстати, оказался успешным; спасибо всем, ваши просмотры и комментарии буквально заставляют меня двигаться дальше!) – сегодняшний пост посвящён реализации объектов в Python 3.x. Поначалу я думал, что это простая тема. Но даже когда я прочитал весь код, который нужно было прочитать перед тем, как написать пост, я с трудом могу сказать, что объектная система Питона… гхм, «простая» (и точно не могу сказать, что до конца разобрался в ней). Но я ещё больше убедился, что реализация объектов — хорошая тема для начала. В следующих постах мы увидим, насколько она важна. В то же время, я подозреваю, мало кто, даже среди ветеранов Питона, в полной мере в ней разбирается. Объекты слабо связаны со всем остальным Питоном (при написании поста я мало заглядывал в
./Python
и больше изучал
./Objects
и
./Include
). Мне показалось проще рассматривать реализацию объектов так, будто она вообще не связана со всем остальным. Так, будто это универсальный API на языке C для создания объектных подсистем. Возможно, вам тоже будет проще мыслить таким образом: запомните, всё это всего лишь набор структур и функций для управления этими структурами.

Всё в Питоне — объект: числа, словари, пользовательские и встроенные классы, стековые фреймы и объекты кода. Чтобы указатель на участок памяти можно было считать объектом, необходимы как минимум два поля, определённые в структуре
./Include/object.h
:
PyObject
:

<code class="objectivec">typedef struct _object {
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;
</code>
Многие объекты расширяют эту структуру, добавляя необходимые поля, но эти два поля должны присутствовать в любом случае: счётчик ссылок и тип (в специальных отладочных сборках добавляется пара загадочных полей для отслеживания ссылок).

Счётчик ссылок — это число, показывающее, сколько раз другие объекты ссылаются на данный. В коде
>>> a = b = c = object()
инициализируется пустой объект и связывается с тремя разными именами:
a
,
b
и
c
. Каждое имя создаёт новую ссылку на объект, но при этом объект создаётся единожды. Связывание объекта с новым именем или добавление объекта в список создаёт новую ссылку, но не создаёт новый объект! На эту тему можно ещё много говорить, но это больше относится к сборке мусора, а не к объектной системе. Я лучше напишу об этом отдельный пост, вместо того, чтобы разбирать этот вопрос здесь. Но, прежде чем оставить эту тему, скажу, что теперь нам проще понять макрос
./Include/object.h
:
Py_DECREF
, с которым мы встретились в первой части: он всего лишь декрементирует
ob_refcnt
(и освобождает ресурсы, если
ob_refcnt
принимает нулевое значение). На этом пока покончим с подсчётом ссылок.

Остаётся разобрать
ob_type
, указатель на тип объекта, центральное понятие объектной модели Питона (имейте в виду: в третьем Питоне, тип и класс по сути одно и то же; по историческим причинам использование этих терминов зависит от контекста). У каждого объекта всего один тип, который не меняется в течение жизни объекта (тип может поменяться в чрезвычайно редких обстоятельствах. Для этой задачи не существует API, и вы вряд ли читали бы эту статью, если бы работали с объектами с изменяющимися типами). Важнее, может быть, то, что тип объекта (и только тип объекта) определяет, что можно с ним делать (пример в спойлере после этого абзаца). Как вы помните из первой части, при выполнении операции вычитания вызывается одна и та же функция (
PyNumber_Subtract
) вне зависимости от типа операндов: для целых чисел, для целого и дробного или даже для полнейшего абсурда, вроде вычитания исключения из словаря.

Показать код
<code class="python"># тип, а не экземпляр, определяет, что можно делать с экземпляром
>>> class Foo(object):
...     "I don't have __call__, so I can't be called"
... 
>>> class Bar(object):
...     __call__ = lambda *a, **kw: 42
... 
>>> foo = Foo()
>>> bar = Bar()
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Foo' object is not callable
>>> bar()
42
# может добавить __call__?
>>> foo.__call__ = lambda *a, **kw: 42
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Foo' object is not callable
# а если добавить его к Foo?
>>> Foo.__call__ = lambda *a, **kw: 42
>>> foo()
42
>>></code>

Поначалу это кажется странным. Как одна сишная функция может поддерживать любой вид передаваемых ей объектов? Она может получить указатель
void *
(на самом деле, она получит указатель
PyObject *
, но это мало что значит, потому что учитываются данные объекта), но как она определит, что делать с полученным аргументом? Ответ заключён в типе объекта. Тип также является объектом (у него есть и счётчик ссылок, и его собственный тип; тип большинства типов —
type
), но в дополнение к двум основным полям он содержит множество других полей. Определение структуры и описание её полей изучайте здесь. Само определение находится в
./Include/object.h
:
PyTypeObject
. Я рекомендую обращаться к нему по ходу чтения статьи. Многие поля объекта типа называются слотами и указывают на функции (или на структуры, указывающие на родственные функции), которые будут выполнены при вызове функции C-API Питона на объектах этого типа. И хоть нам и кажется, что
PyNumber_Subtract
работает с аргументами разных типов, на самом деле типы операндов разыменовываются и вызывается специфичная данному типу функция вычитания. Таким образом, функции C-API не универсальные. Они полагаются на типы и абстрагируются от деталей, и создаётся впечатление, что они работают с любыми данными (при этом выбрасывание исключения
TypeError
— это тоже работа).

Давайте разберём детали.
PyNumber_Subtract
вызывает универсальную функцию двух аргументов
./Objects/abstract.c
:
binary_op
, указав, что работать нужно со слотом
nb_subtract
(подобные слоты есть и для других операций, например,
nb_negative
для отрицания чисел или
sq_length
для определения длины последовательности).
binary_op
— это обёртка с проверкой ошибок над
binary_op1
, функцией, которая выполняет всю работу.
./Objects/abstract.c
:
binary_op1
(почитайте код этой функции — на многое открывает глаза) принимает операнды операции
BINARY_SUBTRACT
как
v
и
w
, и пытается разыменовать
v->ob_type->tp_as_number
, структуру, содержащую указатели на функции, которые реализуют числовой протокол.
binary_op1
ожидает найти в
tp_as_number->nb_subtract
C-функцию, которая либо выполнит вычитание, либо вернёт специальное значение
Py_NotImplemented
, если определит, что операнды несовместимы в качестве уменьшаемого и вычитаемого (это приведёт к выбрасыванию исключения
TypeError
).

Если вы хотите изменить поведение объектов, то можете написать расширение на C, которое переопределит структуру
PyTypeObject
и заполнит слоты так, как вам хочется. Когда мы создаём новые типы в Питоне (
>>> class Foo(list): pass
создаёт новый тип, классы и типы — одно и то же), мы не описываем вручную какие-либо структуры и не заполняем никаких слотов. Но почему тогда эти типы ведут себя так же, как и встроенные? Правильно, из-за наследования, в котором типизация имеет значительную роль. У Питона уже есть некоторые встроенные типы, вроде
list
и
dict
. Как было сказано, у этих типов есть определённые функции, заполняющие соответствующие слоты, что даёт объектам нужное поведение: например, изменяемость последовательности значений или отображение ключей на значения. Когда вы создаёте новый тип в Питоне, на куче для него (как для любого другого объекта) динамически определяется новая C-структура и её слоты заполняются соответственно наследуемому, базовому, типу (вы можете спросить, а что же со множественной наследуемостью?, отвечу, в других эпизодах). Т.к. слоты скопированы, вновь сознанный подтип и базовый обладают почти идентичной функциональностью. В Питоне есть базовый тип без какой-либо функциональности —
object
(
PyBaseObject_Type
в C), в котором почти все слоты обнулены, и который можно расширять без наследования чего бы то ни было.

Таким образом, вы не можете создать тип в Питоне, вы всегда наследуетесь от чего-то другого (если вы определите класс без явного наследования, то он неявно будет наследоваться от
object
; в Python 2.x в таком случае будет создан «классический» класс, их мы не будем рассматривать). Естественно, вам не обязательно постоянно наследовать всё. Вы можете изменять поведение типа, созданного прямо в Питоне, как было показано в сниппете выше. Определив специальный метод __call__ у класса
Bar
, мы сделали экземпляры этого класса вызываемыми.

Что-то, где-то, во время создания нашего класса, замечает этот метод
__call__
и связывает его со слотом
tp_call
.
./Objects/typeobject.c
:
type_new
— сложная, важная функция — это и есть то место, где всё это происходит. Мы подробнее познакомимся с этой функцией в следующем посте, а сейчас обратим внимание на строку почти в самом конце, после того, как новый тип уже был создан, но перед его возвращением:
fixup_slot_dispatchers(type);
. Эта функция пробегается по всем корректно названным методам, определённым в новом типе, и связывает их с нужными слотами в структуре типа, основываясь на именах методов (но где хранятся эти методы?).

Ещё один непонятный момент: каким образом определение метода
__call__
в типе после его создания делает экземпляры этого типа вызываемыми, даже если они были инстанциированы до определения метода? Легко и просто, мои друзья. Как вы помните, тип — это объект, а тип типа —
type
(если у вас разрывается голова, выполните:
>>> class Foo(list): pass ; type(Foo)
). Поэтому, когда мы делаем что-то с классом (можно было бы писать и слово тип вместо класса, но т.к. «тип» мы используем в другом контексте, давайте будем некоторое время называть наш тип классом), например, вызываем, вычитаем или определяем атрибут, разыменовывается поле
ob_type
объекта класса, и обнаруживается, что тип класса —
type
. Затем для установки атрибута используется слот
type->tp_setattro
. То есть класс, может иметь отдельную функцию установки атрибутов. И такая специфичная функция (если хотите зафрендить её на фейсбуке, вот её страничка —
./Objects/typeobject.c
:
type_setattro
) вызывает ту же самую функцию (
update_one_slot
), которую использует
fixup_slot_dispatchers
для урегулирования всех вопросов после определения нового атрибута. Вскрываются новые детали!

На этом, наверное, стоит закончить введение в объекты Питона. Надеюсь, поездка доставила вам удовольствие, и вы до сих пор со мной. Должен признать, что писать этот пост оказалось гораздо сложнее, чем я предполагал (и без помощи Antoine Pitrou и Mark Dickins поздней ночью на
#python-dev
я бы скорее всего сдался!). У нас осталось ещё много интересного: какой слот операнда используется в бинарных операциях? Что происходит при множественном наследовании, и что насчёт тех жуткихмельчайших деталях, связанных с ним? А что с метаклассами? А
__slots__
и слабые ссылки? Что творится во встроенных объектах? Как словари, списки, множества и их собраться выполняют свою работу? И напоследок, что насчёт этого чуда?

<code class="python">>>> a = object()
>>> class C(object): pass
... 
>>> b = C()
>>> a.foo = 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
>>> b.foo = 5
>>>
</code>
Каким образом можно просто так добавить произвольный атрибут в
b
, экземпляр класса
C
, который наследуется от
object
, и нельзя сделать то же самое с
a
, экземпляром того же самого
object
? Знающие могут сказать: у
b
есть
__dict__
, а у
a
нет. Да, это так. Но откуда тогда взялась эта новая (и совершенно нетривиальная!) функциональность, если мы её не наследуем?

Ха! Я безумно рад таким вопросам! Ответы будут, но в следующем эпизоде.



Небольшой список литературы для любопытствующих:

  • документация по модели данных (питонячья сторона силы);
  • документация C-API по абстрактным и конкретным объектом (сишная сторона силы);
  • descrintro, или Унификация типов и классов в Python 2.2, длинная, мозговыносящая и чрезвычайно важная археологическая находка (считаю, что её следует добавить в интерпретатор в качестве пасхалки, предлагаю
    >>> import THAT
    );
  • но прежде всего этот файл —
    ./Objects/typeobject.c
    . Читайте его снова и снова, до тех пор, пока в слезах не рухнете на кровать.
Приятных сновидений.



Помните! Мы всегда рады встрече с заинтересованными людьми.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


YouTube ради эксперимента предлагает отключить рекламу на сайте

Компания Google запустила неожиданный эксперимент на сайте YouTube: каждый пользователь может полностью отключить рекламу на сайте, в том числе текстовую рекламу внутри видео. Судя по всему, эксперимент проводят в рамках стандартного A/B-тестирования, компания просто хочет изучить, как посетители работают с сайтом в отсутствии рекламы.

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

Для этого нужно зайти на сайт youtube.com, после чего в браузере запустить консоль:

  • Chrome/Opera 15+ — Ctrl+Shift+J под Windows/Linux/ChromeOS или Command-Option-J под Mac;
  • Firefox — Ctrl+Shift+K под Windows/Linux или Command-Option-K под Mac;
  • Opera 12 — Ctrl+Shift+I под Windows/Linux или Command-Option-I под Mac, затем нахать «Console»;
  • Internet Explorer — F12 и выбрать «Console».
В окне консоли вставляем следующую команду:

document.cookie="VISITOR_INFO1_LIVE=oKckVSqvaGw; path=/; domain=.youtube.com";window.location.reload();


и нажимаем Enter.

Было:


Стало:


Теперь мы больше не увидим рекламы при посещении сайта YouTube. Впрочем, пользователи AdBlock Plus или тому подобных расширений, наверное, не заметят никакой разницы. Хотя Google и платит разработчикам Adblock Plus за включение своей рекламы в белый список, но этот список можно отредактировать.

В любом случае интересно, что Google проводит такие эксперименты, ведь компания несёт прямые финансовые убытки от исчезновения рекламы.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


[Перевод] Руководство по WebKit-атрибуту srcset в тэге img

Свободный движок WebKit теперь поддерживает srcset атрибут изображений, IMG элементов (официальная спецификация от W3C). Это позволяет вам, как разработчику, использовать картинки с высоким разрешением для пользователей использующих ретина-дисплей без ущерба для остальных пользователей. Также важно отметить о наличие изящного решения для браузеров, которые еще не поддерживают данный функционал.

Обратите внимание, в необходимости использовать последние ночные сборки WebKit.

Тестируем свой браузер. Видите синюю картинку — не поддерживает. Красную — браузер выбрал вариант 1х, зеленую — браузер выбрал вариант 2х. Под спойлером подробней.

Возможно, вы знаете, что WebKit поддерживает -webkit-image-set CSS функцию чуть более года (Safari начиная с 6 версии и Google Chrome начиная с 21 версии). С помощью данной функции появилась возможность задавать в css-свойствах изображения в зависимости от разрешения экрана, или другого устройства воспроизведения, каждое с модификатором 1х, 2х.

<code class="css">.class {
  /* задаем фоновое изображение, если браузер не поддерживает image-set */
  background-image: url(image-set-not-supported.png);
  /* задаем фоновые изображения, для различных разрешений */
  background-image: -webkit-image-set(url(low-res-image.jpg) 1x, url(high-res-image.jpg) 2x);
}
</code>
Это позволит браузеру выбрать наилучший вариант для конкретного устройства пользователя. Прежде, для поддержки больших картинок у вас было несколько путей развития, каждый с определенными недостатками. Вы могли дублировать CSS код. Вы могли использовать JavaScript для запроса (window.devicePixelRatio) количества точек на px. (device pixel ratio) и обновлять картинки после загрузки страницы. Или вы могли всегда отдавать большие картинки, тем самым заставляя некоторых пользователей грузить лишнее. И если вам необходимы были картинки с разными разрешениями приходилось уточнять связанные CSS свойства, такие как background-size как часть border-image. Это раздражало.

К счастью, -webkit-image-set позволяет написать вам одно простое правило, тем самым заставив браузер самому определять более подходящую картинку и как следствие её и загружать.

Srcset атрибут очень похож на -webkit-image-set. В самом деле, можно подумать об атрибуте как об эквивалентной функции CSS. Аналогично списку картинок в -webkit-image-set, вы добавляете новый атрибут srcset к вашим графическим элементам. Поддерживается обратная совместимость, браузеры не поддерживающие srcset, игнорируют его и продолжают использовать src. А вся прелесть в том, что браузерный движок глянет на srcset и сам определит наилучшую картинку к загрузке. В большинстве случаев вам необходимо написать вот так:

<code class="html"><img src="normal-image.jpg" srcset="better-image.jpg 2x">
</code>
Обратили внимание на “2x” после “better-image.jpg”? Это говорит браузеру, что для экранов устройств с devicePixelRatio = 2 и более, необходимо использовать better-image.jpg взамен normal-image.jpg. И если экран устройства не «ретина», браузер обратится к атрибуту src. Вы также можете задавать значение 1х атрибута srcset, как в примере ниже.

Srcset атрибутНиже приведено изображение — img элемент с обоими атрибутами: src и srcset. Существует стиль устанавливающий размер картинки в 400x400px. В браузерах без поддержки srcset, будет использоваться значение src, а следовательно загрузится стандартная картинка:
image

На обычных экранах будет загружаться вариант 1х srcset атрибута:
image

На ретина дисплеях будет загружаться вариант 2х srcset атрибута:
image

HTML код примера:
<code class="html"><img src="image-src.png" srcset="image-1x.png 1x, image-2x.png 2x">
</code>



Больше об srcset можно прочитать в официальной спецификации. Обратите внимание, что на данный момент только WebKit поддерживает «коэффициенты разрешений» — 1x, 2x, 3x. Как и любой новый функционал, WebKit может содержать ошибки, поэтому будьте бдительны. В частности, вы должны убедиться, что WebKit загружает минимальные ресурсы для страницы, потому что это одна из целей этой функции.

Особая благодарность членам сообщества WebKit Romain Perier и Yoav Weiss которые внесли важный вклад (r153624, r153733) в развитие данного функционала.

P.S. Замечания по переводу присылайте в личку.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Во Флориде собираются использовать беспилотники для борьбы с москитами


Первый запуск Страж-птицы беспилотника Maveric во Флориде.

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

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

Но вернемся к роботам. Беспилотный ЛА, видный на анонсной фотографии, очень похож на «Страж-птицу» (кто не читал Шекли, обязательно ознакомьтесь). Правда, эта «птичка» не сможет поражать москитов или личинок электрическим разрядом, как описывается в НФ рассказе Шекли. Нет, беспилотники используются для получения инфракрасной карты региона. Чем теплее водоем, тем больше в нем личинок москитов. И ученые/санитарные службы отправятся именно в такие места для борьбы с личинками кровососов.

Созданы беспилотники компанией Condor Aerial, а название такого аппарата — Maveric. Вполне может быть, что «птичек» в недалеком будущем еще и оснастят каким-нибудь «противоличиночным оружием», типа химикатов, которые будут сбрасываться в водоемы. Это звучит все менее фантастично. Пока что об этом никто не говорит, само собой, но почему бы и не предположить нечто подобное?

Сам эксперимент будет проводиться в конце этого месяца.

Вот демонстрация работы БЛА Maveric (видео не относится к текущему проекту, но дает возможность оценить «умения» роботов):


Via IEEE Spectrum

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Пересёк границу — потерял электронные книги

Американец Джим О’Доннелл (Jim O'Donnell) находился на библиотечной конференции в Сингапуре, когда заметил сообщение о новых обновлениях для приложений на своём айпаде. Среди них было и Google Play Books. Как известно, в некоторых странах через Google Play можно покупать не только приложения, но и электронные книги (https://play.google.com/store/books). О’Доннелл в своё время купил от 30 до 40 книг, многие из которых нужны были ему для работы, пишет он в своём блоге.

После обновления программа сказала, что нужно заново скачать файлы электронных книг и это займёт несколько минут. Однако, процесс так и не завершился. Как выяснилось, в странах, где сервис Google Books недоступен (а это большинство стран мира), он уже не имеет права скачивать книги, даже если и купил их ранее на территории другой страны. Судя по всему, это не баг, и именно фича системы управления цифровыми правами DRM — файлы книг были удалены с планшета (un-downloaded).



Интенсивный письмами со службой поддержки Google Play не дал результата. Пользователю объяснили, что нужно вернуться на территорию США, где он сможет заново скачать свои книги. Любопытно, что на одном из этапов переписки представители поддержки спросили, что бы он хотел улучшить в Google Play. Джим О’Доннелл ответил одной фразой: “Don't Be Evil”. На это письмо ему ничего не ответили.

К счастью, О’доннелл сумел найти копию книги 19-го века, которая нужна была ему больше всего, в хранилище archive.org. Он загрузил файл и открыл его в GoodReader — этой программе было всё равно, в какой стране он находится.

Вероятно, приобретая электронные книги, защищённые DRM, покупатель не получает права собственности на них, а всего лишь платит за право чтения этих книг. Владелец смежных прав на интеллектуальную собственность определяет, на территории каких стран можно предоставлять такое право. Если ты пересёк за границу — можешь лишиться этой привилегии. Аналогичная система DRM может действовать и в отношении программного обеспечения и другого контента, хотя в случае с книгами это выглядит особенно дико. Хорошо хоть не заставляют забыть прочитанное.

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

«Право прочесть»Для Дана Хeлберта дорога к Тихо началась в училище — когда Мелисса Ленц попросила одолжить ей его компьютер. Ее компьютер сломался, и если бы она не смогла найти другой, она завалила бы свою курсовую работу. Она не осмеливалась просить никого, кроме Дана.

Это поставило Дана перед дилеммой. Ему необходимо было помочь ей — но если бы он одолжил ей свой компьютер, она могла бы прочесть его книги. Даже если забыть тот факт, что ты мог попасть на много лет в тюрьму за то, что дал читать свои книги кому-то еще, уже сама идея поначалу приводила его в ужас. Его, как и всех, с начальной школы учили, что обмениваться книгами гадко и противно — так делают только пираты.

А шанс, что SPA — Служба охраны программного обеспечения — не сумеет поймать его, был невелик. На занятиях по программированию Дан узнал, что в каждой книге есть средство контроля авторских прав, которое докладывает в Лицензионный центр, когда ее читали, где и кто. (Они пользовались этими сведениями, чтобы отлавливать читающих пиратов, а также чтобы продавать данные о личных интересах магазинам.) Как только его компьютер подключили бы к сети, Лицензионный центр узнал бы об этом. Он как владелец компьютера получил бы самое строгое наказание — за то, что не побеспокоился предотвратить преступление.

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

Впоследствии Дан узнал, что было время, когда любой мог зайти в библиотеку и почитать статьи в журналах и даже книги, и за это не приходилось платить. Существовали независимые ученые, которые читали тысячи страниц без государственных субсидий на библиотеки. Но в девяностых годах XX века как коммерческие, так и некоммерческие издания начали взимать плату за доступ. К 2047 году публичные библиотеки со свободным доступом к научной литературе стали смутным воспоминанием.

Конечно, были способы обойти SPA и Лицензионный центр. Они сами были незаконны. У Дана был сокурсник по программированию, Френк Мартуччи, который достал запрещенное средство отладки и применял его для обхода программы контроля авторских прав, когда читал книги. Но он рассказал об этом слишком многим знакомым, и один из них сдал его в SPA за вознаграждение (когда студент попал в глубокую долговую яму, его легко подбить на предательство). В 2047 году Френк сидел в тюрьме — не за пиратское чтение, а за то, что у него был отладчик.

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

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

Можно было также обойти средства контроля авторских прав, установив измененное ядро системы. Дан со временем узнал о свободных ядрах, даже целых свободных операционных системах, которые существовали на рубеже веков. Но они были не только незаконны, как отладчики — их нельзя было установить, даже если они у тебя были, если ты не знал пароля администратора для своего компьютера. А его ты не узнал бы ни от ФБР, ни от службы поддержки Microsoft.

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

Дан разрешил дилемму, сделав нечто еще более немыслимое: он одолжил ей компьютер и сказал ей свой пароль. Таким образом, если бы Мелисса стала читать его книги, Лицензионный центр подумал бы, что их читает он. Это тоже было преступлением, но SPA не узнал бы об этом автоматически. Они узнали бы, только если бы Мелисса донесла на него.

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

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

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

Мелисса не донесла на Дана в SPA. Его решение помочь ей привело к тому, что они поженились, а также поставило перед ними вопрос о том, что им в детстве говорили о пиратстве. Супруги стали читать об истории авторского права, о Советском Союзе с его запретами на копирование и даже о первоначальной Конституции Соединенных Штатов. Они переехали на Луну, где они нашли других людей, которые тоже улетели туда, чтобы длинные руки SPA не могли их достать. Когда в 2062 году началось восстание в Тихо, всеобщее право прочесть быстро стало одной из его основных целей.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Самая популярная статья в научном журнале

В начале 2000-х годов научные журналы только начали публиковать свои материалы в онлайне. Большинство читателей оформляли платную подписку за бумажную версию, а покупка цифровых копий была редкостью. Тем не менее, издатели понимали, что будущее — за цифровой доставкой контента, поэтому открывали сайты и внимательно следили за посещаемостью, вспоминает молекулярный биолог Ричард Грант в своём блоге.

Одним из первых онлайновую версию открыл «Журнал молекулярной биологии» (“Journal of Molecular Biology”) от издательства Elsevier. Как и предполагалось, в первое время посещаемость сайта была крайней малой. Но вскоре в редакции заметили, что одна из статей в выпуске 324, том 1, за 15 ноября 2002 года пользуется повышенной популярностью. Посещаемость этой страницы была во много раз больше, чем у всех остальных. Статья называлась «Молекулярный анализ, локализация ткани и связей Ca2+ рианодинового рецептора Caenorhabditis elegans».

Руководство журнала задалось вопросом, что же такого интересного в научной статье о Caenorhabditis elegans.

Caenorhabditis elegans — свободноживущая нематода (круглый червь) длиной около 1 мм. Это хорошо изученное животное с некоторыми интересными и важными свойствами. Широко используется как модельный организм в исследованиях по генетике, нейрофизиологии, биологии развития, вычислительной биологии. Впрочем, уникальность червя вряд ли могла оправдать столь огромный интерес широкой публики, тем более что никто из посетителей не оплачивал доступ к полной версии статьи, а удовлетворялись чтением реферата — краткого содержания.



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

Загадку смогли разгадать, когда редакция внимательно прочитала содержимое реферата, содержавшего такую строчку:

«CeRyR найден в стенке тела, глотке, вульве, анальных и сексуальных мышцах взрослых червей, а также в эмбриональных мышцах, но отсутствует в не-мышечных клетках».

CeRyR was found in the body wall, pharyngeal, vulval, anal and sex muscles of adult worms and also found to be present in embryonic muscle, but not in non-muscle cells.
Нужно иметь в виду, что слово [and] игнорируется поисковыми системами при обработке запроса, потому что распознаётся как оператор.

«В этой истории есть какая-то мораль, но не могу понять, какая именно», — с грустью признаёт Ричард Грант.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Разработчик сообщил о баге в Facebook на страницу Цукерберга

image

Если ваша страница в Facebook не является публичной, то другие, по идее, не имеют возможности что-либо на ней писать. Однако разработчик из Палестины Халил Шритех обнаружил уязвимость, которая позволяла любому пользователю разместить ссылку на чужой странице, пишет The Verge.

Шритех сообщил об ошибке в Facebook в надежде получить вознаграждение, но компания проигнорировала проблему, ответив, что это не баг. В итоге он, используя этот же баг, запостил сообщение о нём прямо на страницу Марка Цукерберга.

Перед тем, как сообщить о баге в Facebook, Шритех протестировал его на Саре Гудин — подруге Цукерберга. В письме в Facebook он описал подробности, отметив, что служба безопасности может не увидеть его пост на странице Гудин, поскольку её профиль открыт только для друзей. Несмотря на прикреплённый скриншот поста, инженер Facebook, назвавшийся Эмракулом, ответил: «Я сожалею, но это не ошибка».

Неудовлетворённый ответом, Шритех решил самостоятельно уведомить Марка Цукерберга о баге, разместив пост на его странице. Через несколько минут инженер Facebook Ола Окелола связался со Шритехом, запросив подробную информацию о баге. Facebook отключил аккаунт Шритеха, по-видимому опасаясь других последствий.

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

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Скульптура леммингов от DMA Design открыта в городе Данди (Шотландия)

В 1991 компанией DMA Design были созданы, возможно, самые очаровательные существа в игровом мире, известные как лемминги (Lemmings). Никто тогда не мог предположить, что в скором будущем они станут легендарными героями. Учитывая, что эти классические создания родом из города Данди, местный совет решил увековечить их в виде скульптуры, возведенной в районе Seabraes.



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

Так как компания DMA (Doesn't Mean Anything) Design больше не существует в своем первоначальном виде (с 2002 года компания переименована в Rockstar Games), то эта скульптурная композиция леммингов обретает символическое значение, увековечив также и память об этой компании, такой важной для города в целом.


UPD: Для тех кто в танке (спасибо Vokabre за подсказку):



Источник: habrahabr.ru,
получено с помощью rss-farm.ru


[Из песочницы] Балансировка трафика в Mikrotik между двумя WAN-интерфейсами с учетом входящего трафика

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

Сразу предупреждаю – система имеет много недостатков, например возможны обращения к одному и тому же ресурсу с разных IP, что чревато слетом авторизации. Так что использовать ее лучше всего для подключений которые не чувствительны к source address, тем же торентам например.

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

Для совсем новичков и людей слабо разбирающихся в сетях(можно быть мастером в одном и новичком в другом, ничего необычного в таком не вижу) я разместил пару спойлеров
Итак. Условно примем что:
— локальные адреса у нас лежат в диапазоне 192.168.0.0/16 и подключены к бриджу Localca
— Провайдер1 сидит у нас на интерфейсе WAN1, с шлюзом 10.0.0.1
— Провайдер2 сидит у нас на интерфейсе WAN2, с шлюзом 172.16.25.1

Итак приступим.

Первым делом создадим новые маршруты:

<code class="bash">/ip route
add disabled=no distance=1 dst-address=192.168.0.0/16 gateway=Localca routing-mark=isp2 scope=30 target-scope=10
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=172.16.25.1 routing-mark=isp2 scope=30 target-scope=10
add disabled=no distance=1 dst-address=192.168.0.0/16 gateway=Localca routing-mark=isp1 scope=30 target-scope=10
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=10.0.0.1 routing-mark=isp1 scope=30 target-scope=10
</code>
Что такое роуты, они же маршрутыМаршруты это указание роутеру на каком порту или за каким IP-адресом искать нужную подсеть. Без этого роутер не будет знать куда отсылать пакеты. Вот поэтому мы и указали не только шлюзы для интернета но и порт на котором находятся наши локальные адреса

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

Cоздадим мангл который будет все новые коннекты отправлять на нужный шлюз:

<code class="bash">/ip firewall mangle
add action=mark-connection chain=prerouting connection-mark=no-mark disabled=no dst-address=!192.168.0.0/16 new-connection-mark=inet_con passthrough=yes
add action=mark-routing chain=prerouting comment=multiwan  connection-mark=inet_con disabled=no new-routing-mark=isp2 passthrough=no
</code>

Первое правило ловит все не промаркированные (а значит новые) коннекты которые идут не в нашу локалку, а следовательно пойдут через WAN интерфейс, и маркирует их нужной меткой. Я выбрал такой подход, так как ВАН интерфейсов у нас несколько, и для каждого пришлось бы создавать отдельное правило с нужным Out. Interface, а так мы ограничились одним правилом. Второе правило коннектам с нужной меткой назначает марк роутинга. Comment служит нам для того что бы мы могли найти это правило скриптом.
mark-routing, для чего онМарк роутинга служит для указания таблицы маршрутизации выбранным пакетам/соединениям. Они будут использовать только те роуты которые несут соответствующий Routing Mark. Таким методом мы можем разный трафик отправлять на разные шлюзы/порты по нужных нам условиях. Все что левее закладки Action в манглах(да и в фильтре и NAT) это фильтр. Так что чем меньше мы критериев укажем тем шире будет охват подпадающего под это правило трафика. Соответственно комбинируя разные условия мы очень точно может отделить нужный нам трафик.


Следующим пунктом мы идем в System-Scripts и создаем новый скрипт вот такого вот содержания:

<code class="bash">:global rx1 "0"
:global rx2 "0"
/interface monitor WAN1 once do={ 
   :global rx1 $("rx-bits-per-second"); 
} 
/interface monitor WAN2 once do={ 
   :global rx2 $("rx-bits-per-second"); 
} 
:local one 20000000
:local two 8000000
:global wan1  ($one / $rx1)
:global wan2 ($two / $rx2)
if ($wan1>$wan2) do={/ip firewall mangle set [find comment=multiwan] new-routing-mark=isp1} else={/ip firewall mangle set [find comment=multiwan] new-routing-mark=isp2}
</code>

Сначала мы обнуляем переменные, потом получаем в эти переменные данные о загруженности интерфейсов(а конкретно то количество получаемых бит в секунду, за что отвечает параметр rx-bits-per-second). Дальше в переменные one и two вписываем ширину каждого интернет-канала в битах, и получаем обратную(так как микротик не показывает дробную часто то при делении количества бит на ширину мы бы получили 0) относительную загруженность(делим ширину на загруженность в битах). А потом их сравниваем, и если число больше у первого ВАНа то в наш мангл(здесь и пригодился комментарий, по нему мы и обратились к нужному манглу) вписываем роутмарк для ВАН1, иначе к ВАН2.
Теперь дело за малым – задать периодичность исполнения скрипта. Идем в System-Sheduler и добавляем новую задачу с нужным интервалом исполнения, в поле on Event: вписываем

<code class="bash">/system script run erazel_balancing
</code>

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

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

<code class="bash">add action=mark-connection chain=prerouting connection-mark=no-mark disabled=yes dst-address=!192.168.0.0/16 new-connection-mark=inet_con passthrough=yes protocol=tcp src-port=45000
</code>

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


[Из песочницы] О научных ротах программистов

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

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

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

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

Для чего создаются научные роты программистов?
Если кратко, то руководство страны решило наверстать наше отставание в информационных технологиях от других стран (таких как США). В частности, одним из проектов является перенос деятельности министерств на цифровую основу и создание некой собственной сети для связи всех узлов управления страной. Проект очень масштабный, и, насколько я понял, в первую очередь призван улучшить обороноспособность страны. Контр-адмирал, например, сравнил его с созданием атомной бомбы СССР.

Почему именно сейчас?
Вот так вот вышло. В качестве слухов и сплетен: есть информация, что за несколько дней до этой беседы президент провёл совещание, по результатам которого было спешно принято решение о создании научных рот.

Кого берут в научные роты программистов?
В первую очередь это выпускники ВУЗов и магистранты (на счёт аспирантов не уверен). Теоретически, тот, кто закончил летом третий курс, так же может записаться, но тогда ему придётся предоставить некую рекомендацию от научного руководителя, мол тоже не дурак. Интересно, что допускается возможность участия в этом проекте граждан других государств. В первую очередь это касается Беларуси, как союзного государства.

Чем будут заниматься в этих ротах?
Сразу стоит сказать, что участие в этом проекте означает прохождение воинской службы. Соответственно, если человек не служил, то это отличный шанс совместить приятное с полезным.
Заниматься придётся в первую очередь научной деятельностью. Т.е. сначала вы пройдёте курс молодого бойца, дадите присягу, а потом уже начнёте делать непосредственно то, ради чего всё это и затевалось. Никто не будет заставлять бегать по плацу в сапогах и заниматься чисткой туалетов. Фактически, вы будете ходить на работу как обычный гражданский, но в то же время будете являться военнослужащим.

Берут всех желающих?
Нет, далеко не всех.
Во-первых существует строгий отбор. Точными цифрами не владею, но из огромного количества желающих (несколько тысяч человек) в роты возьмут только несколько сотен. При отборе будет учитываться как научная подготовка, так и заинтересованность.
Во-вторых человек должен элементарно подходить для службы. Т.е. лиц старше 27 лет вряд ли возьмут, да и минимальная физическая подготовка необходима. К слову, есть некоторые проблемы с теми, кто учился в своё время на военной кафедре. Это связано с тем, что такой человек уже имеет звание (лейтенант запаса, если я не ошибаюсь), а научные роты можно рассматривать как призыв на срочную службу.
Но все проблемы решаемы, особенно если у человека есть желание (контр-адмирал говорил, что всё это можно пересмотреть).

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

Сколько времени продлится служба?
Служба продлится год. Первый месяц вы проходите КМБ, после чего принимаете присягу. Следующие два месяца вы будете искать пути решения выданной вам задачи. Если ваш путь устраивает научного руководителя (будет приставлен к вам уже на месте прохождения службы), то можно приступить к выполнению задачи, а каждый следующий месяц отчитываться о проделанной работе.

А что будет, если у меня не получится/я не захочу?
Если у вас что-то не выходит, то всегда можно обратиться к научруку. В любом случае за это наказывать не будут =) Если же вы изъявляете нежелание продолжать научную деятельность на благо Родины, вас, вероятно, просто отправят в другую часть для прохождения уже обычной срочной службы. При том выбор части остаётся за начальством. Таким образом, если всё хорошо, то сидеть вам в каптёрке, а вот если имели место случаи нарушения дисциплины, то могут отправить служить куда подальше и в часть похуже.

Какие условия на месте службы?
Обещали, что всё будет на уровне. Не люкс, конечно, но и в казарме жить вы не будете. Собственно, из-за проблем с жильём количество набираемых рот сократилось.

А у меня жена/дети?
Эти проблемы тоже называли решаемыми. Если вы уже успели обзавестись супругой, то, вероятно, ей тоже предоставят жильё. Касательно детей ничего не могу сказать.
Вообще, судя по тому, что говорили представители минобороны, можно было понять, что они готовы решать проблемы научных работников. Главное чтобы последние усердно делали свою работу.

А что с секретностью?
Уровень допуска позволит выезжать за границу. Так же некоторые вещи вы сможете обсуждать со своими друзьями, но, конечно, это всё будет регламентировано.

Что мне за это будет?
Рассчитывать на какое-то денежное вознаграждение вряд ли приходится, однако обещали какие-нибудь бонусы (да, да, всё туманно).

Когда нужно (было) дать ответ?
На тот момент для принятия решения у сомневающихся было всего пол дня, от силы сутки. Военные высказывали сожаление о том, что нет больше времени на раздумья, но так случилось. Получили приказ и приступили к выполнению.

Будут ли ещё наборы в научные роты?
Не известно. Это эксперимент, и какие результаты он принесёт — не ясно. В зависимости от этих самых результатов, набор в следующем году могут как увеличить, так и вовсе убрать.

Ну вот и все вопросы, которые мне вспомнились.
Если у Вас есть свои вопросы, то задавайте их в комментариях — попытаюсь ответить.
В завершение могу сказать, что считаю эту возможность отличным вариантом. Если бы я соответствовал критериям, сам с удовольствием записался бы. Где ещё предложат заниматься любимым делом на благо Родины, да ещё и службу в армии проходить?

UPD: вот нашёл в комментариях к посту "о кибервойсках" следующие слова:
Комментарий
enotys
Я в этом году закончил магистратуру СПб НИУ ИТМО по специальности информационная безопасность. Разумеется стал вопрос служить или не служить. Буквально за 2 дня до окончания весеннего призыва — 13 июля (призыв до 15 июля). В ИТМО пришел какой то генерал, который был ответственный именно за набор в эти «легендарные» кибервойска. Там было, что то типа дня открытых дверей. Сам не мог присутствовать т.к. работал, но вот что мне рассказали.

Вопрос:
Магистратура НИУ ИТМО КТиУ
Вниманию тех, кто:
1. Умеет программировать.
2. Годен (можно ограниченно) к воинской службе.
3. Не проходил военную кафедру.
4. Хочет поработать год в Москве при министерстве обороны, и это зачтется в качестве срочной службы

Можно ли где нибудь узнать подробности этой программы? Есть ли там какая то з.п.? Какие языки и технолигии нужно знать? Как решается проблема с проживанием в Москве? Будет ли 40 часовая рабочая неделя или это как срочная служба?

Ответ:
Герман Криммель
Сергей, жильё предоставляет мин. обороны(я так понял что-то вроде казармы), зарплата это денежное довольствие солдата. Фактически это служба в армии, но вместо рытья окопов и строевой ходишь на работу. Говорят даже можно не носить форму и не брить голову. Но там ещё не совсем всё ясно, что и как — завтра только будет директива, которой и будет регламентироваться служба. Примерно так.

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

Это, собственно, в подтверждение того, что по плацу там никто гонять не будет.

Источник: habrahabr.ru,
получено с помощью rss-farm.ru


Набор методов для работы со списками в AngularJS

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

Демка, песочница (с демкой играются многие, так что данные могут скакать)

Как видно из примера, у нас проблема: куча списков со схожей функциональностью (добавление, удаление, сортировка элементов — что еще может быть у списков :-).

Сервис

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

Для нашей задачи используется наиболее простой тип: фабрика:

<code class="javascript">angular.module('oi.list', [])
  .factory('oiList', function () {
            
    return function (scope, Resource) {
      scope.items = Resource.query()
      scope.add = Resource.add()
      ...
    }
  }
</code>
Теперь, внедряя наш сервис в контроллер, получаем функцию, которая записывает в область видимости все необходимые методы.

<code class="javascript">.controller('MyCtrl', ['$scope', 'ListRes', function ($scope, ListRes) {

    oiList($scope, ListRes);
}])
</code>

Кэширование

Хорошо, но можно еще улучшить. При получении данных аяксом ($resource, $http) Ангуляр по-умолчанию кеширует полученные данные. Это означает, например, что загрузив в ng-view страницу с данными, уйдя с нее и снова вернувшись не придется загружать данные заново, т.к. они берутся из кэша.

К сожалению, это работает только в элементарных случаях. Ангуляр кэширует именно запросы, а не модель. Т.е. загрузив и закэшировав массив данных с помощью
Resource.query(), Ангуляр не возьмет данные из кэша если запросить их для отдельного элемента с помощью resArr[0].get()
, потому что запрос будет уже другим. Так как кэш никак не связан с моделью, то его обновление при обновлении модели превращается в нетривиальную задачу.

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

<code class="javascript">.value('oiListCache', {cacheRes: {}})
.factory('oiList', ['oiListCache', function (oiListCache) {
            
    return function (scope, cache, Resource) {
      if (angular.equals(oiListCache.cacheRes[cache], [])) {
       //Загружаем данные с сервера и записываем в кэш
        scope.items = oiListCache.cacheRes[cache] = Resource.query();

      } else {
        //Загружаем данные из кэша
        scope.items = oiListCache.cacheRes[cache];
      }
    }
  }
</code>
Для каждой модели используем характеризующую ее строку
cache, чтобы разные модели имели бы раздельный кэш.

Методы

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

Лучший способ — показать новый элемент сразу, а к базе привязать после получения ответа. И тут кроется большой подвох. Что делать, если пользователь удалил элемент у которого пока нет айдишника? Или одновременно добавил несколько элементов? В таком случае использую счетчик добавляемых/удаляемых элементов. При отправке запроса на добавление/удаление счетчик увеличивается, при получении ответа уменьшается. Код приводить не буду, его легко найти в песочнице.

Известные проблемы

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

  1. В качестве параметров принимаются объект Resource
и ключ для кэша
cache. Если бы из ресурса можно было бы вытащить его имя, то оно бы отлично заменило ключ кэша. К сожалению, не представляю как его достать.

  • При каждом изменении списка новое расположение элементов отправляется на сервер функцией sort(). Проблема в том, что без scope.$$phase || scope.$apply()
  • отправка изменений происходит через раз.

  • Сейчас модель записывается в область видимости под именем scope.items, которое нельзя поменять на другое. Выносить имя отдельной настройкой в параметры не хочется. Хочется в контроллере писать
    $scope.modelname = oiList($scope, 'list', ListRes)
    , но при этом ломается биндинг, т.к. при получении данных с сервера не происходит их прямое присвоение области видимости.



  • Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Perl6 — Работа с типами данных

    До сих пор в статьях было лишь поверхностное упоминание о типах данных — объявление переменной определенного типа, либо указание результата операции, но все что мы могли, это лишь терпеть выходки компилятора — «хочу умру (die), захочу варнинг кину, или просто поменяю тип».
    Собственно, для тех кто хочет почувствовать себя богом хоть как-то важным в управлении типами в своем же скрипте, добро пожаловать под кат.


    Итак, допустим мы написали функцию, которая принимает в качестве параметров две переменные:
    <code>sub Func($a, $b) {...}
    </code>

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

    Начнем с малого — узнаем какой у нас тип данных у каждой из переменной, для этого используем метод WHAT, который вернет type object — объект обозначающий тип данных (например для значения 10 будет возвращен объект "(Int)" ). Следует отметить, что возвращается именно объект, а не строка, и простое сравнение двух типов через, например, == или eq не подойдет. Для того чтобы сравнить полученный объект с типом мы воспользуемся оператором умного сравнения '~~':
    <code>sub Func($a, $b)
    {
     $condition = ( ($a.WHAT ~~ (Rat)) ?& ($b.WHAT ~~ (Str)) );
     $condition ?|= ( ($a.WHAT ~~ (Str)) ?& ($b.WHAT ~~ (Rat)) );
     if ($condition)
      {
         #`(SomeWork)
      }
     else
      {
        #`{AnotherWork}
      }
    }
    </code>
    (Rat) и (Str) являются type object'ами действительных чисел и строк соответственно.
    Для тех кто уже подзабыл ?& — Логическое «И», ?| — Логическое «ИЛИ».

    И так, мы научились определять тип значения переменной, и взависимости от него выполнять какие либо действия. Но давайте посмотрим, в каких именно случаях это делать необходимо:
    <code>my Int $a;
    sub Func($p)
    {
      $a = $p;
    }
    
    Func(10);
    Func("Test");
    </code>
    В нашем случае, скрипт умирает когда пытается переменной, которая может содержать только целые числа, присвоить строку.

    Подкорректируем немного наш пример, и напишем следующее:
    <code>  $a = +($p);
    </code>
    В результате мы так же словим ошибку, и скрипт умрет, а ошибка будет не про присваивание а про неправильный тип в числовом контексте, из чего мы сделаем вывод, что частные контексты лишь добавляют ограничений по типам, и что для ручного преобразованя типов нам нужно что-то другое.

    Попытаемся использовать следующую конструкцию:
    <code>  $a = Int($p);
    </code>
    Уже лучше, так как если мы передадим число типа (Rat), то оно будет преобразовано к типу (Int), но вот если мы передадим строку, то получим уже ошибку преобразования строки в число, а именно о том, что строка должна иметь вид числа в 10-ой системе счисления.
    Пока что я нашел только один способ заставить скрипт работать дальше — отлов исключений. На мой взгляд это самое логичное действие, но об этом мы поговорим в следующих статьях

    Также наш скрипт может умереть если функция попытается вернуть значение, несоответствующее описанию:
    <code>sub Func($p) of Int
    {
      return $p;
    }
    Func("test");
    </code>
    Так что в данном случае, тоже не помешало бы сделать проверку выходных значений.

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Из песочницы] Записи в DNS из NetXMS

    Некоторое время назад наша группа инженеров плотно подсела на систему мониторинга NetXMS. Киллер-фичей оказалась графическая конcоль:

    image

    Ничего настолько же наглядного и удобного (да, это очень субъективный критерий) в знакомых нам OpenNMS и Zabbix нет и близко. Систему мониторинга стало возможно использовать не просто как механизм оповещений о возникающих проблемах, а в первую очередь для анализа текущего состояния сети.

    Мы уже использовали несколько совершенно не связанных друг с другом баз данных, в которых с той или иной стороны учитывалось все или часть эксплуатируемого нами оборудования. Появился соблазн уменьшить количество этих баз данных, взяв БД NetXMS за первичный источник информации. Первой жертвой пал внутренний DNS-сервер.

    Действительно, какой смысл для каждого из нескольких сотен хостов заводить соответствующие записи A и PTR? Пусть мы не слишком напрягались, всего лишь редактируя файл /etc/hosts для dnsmasq, однако можно ведь избежать и этой совершенно ненужной работы.

    Мы выбрали PostgreSQL в качестве СУБД для NetXMS, соответственно нам потребовался DNS-сервер, умеющий доставать как минимум A и PTR из PostgreSQL. Сходу нашлись следующие варианты:

    • Dynamically Loadable Zones для BIND
    • Generic PgSQL backend для PowerDNS
    • Относительная экзотика — реализации DNS-серверов на perl или python, специально предназначенные для расширения собственными обработчиками, к этой же категории можно отнести PipeBackend и RemoteBackend для PowerDNS
    Слишком экзотитческие решения мы отбросили, к bind у нас иррациональное отвращение, поэтому остался PowerDNS. В его конфигурационый потребовалось добавить:

    <code class="bash">load-modules=gpgsql
    launch=gpgsql
    gpgsql-host=nxhost
    gpgsql-dbname=nxdb
    gpgsql-user=nxreader
    gpgsql-password=nxreaderpwd
    recursor=8.8.8.8
    </code>
    PowerDNS ожидает увидеть в БД nxdb следующие таблицы:

    <code class="sql">CREATE TABLE domains (
        id              SERIAL PRIMARY KEY,
        name            VARCHAR(255) NOT NULL,
        master          VARCHAR(128) DEFAULT NULL,
        last_check      INT DEFAULT NULL,
        type            VARCHAR(6) NOT NULL,
        notified_serial INT DEFAULT NULL, 
        account         VARCHAR(40) DEFAULT NULL
    );
      
    CREATE TABLE records (
        id              SERIAL PRIMARY KEY,
        domain_id       INT DEFAULT NULL,
        name            VARCHAR(255) DEFAULT NULL,
        type            VARCHAR(10) DEFAULT NULL,
        content         VARCHAR(65535) DEFAULT NULL,
        ttl             INT DEFAULT NULL,
        prio            INT DEFAULT NULL,
        change_date     INT DEFAULT NULL
    );
    </code>
    Разумеется, таких таблиц там нет, но вместо них есть следующее:

    <code class="sql">nxdb=> SELECT id, name, primary_ip, last_modified FROM nodes INNER JOIN object_properties ON id = object_id;
      id  |          name          |   primary_ip    | last_modified 
    ------+------------------------+-----------------+---------------
        1 | ns                      | 10.1.1.1        |    1376221181
    </code>
    Поэтому требуемые таблицы легко заменяются представлениями:

    <code class="sql">CREATE OR REPLACE VIEW domains AS
        SELECT
            0::INT AS id,
            'domain.local'::TEXT AS name,
            NULL::TEXT AS master,
            NULL::INT as last_check,
            'NATIVE'::TEXT as type,
            NULL::INT as notified_serial,
            NULL::TEXT as account;
    
    CREATE OR REPLACE VIEW records AS
        SELECT
            0::INT AS id,
            0 AS domain_id,
           'domain.local' AS name,
           'SOA'::TEXT AS type,
           'ns.domain.local'::TEXT AS content,
            0 AS ttl,
            NULL::INT AS prio,
            NULL::TEXT AS change_date
        UNION
        SELECT
            id,
            0 AS domain_id,
            LOWER(name) AS name,
            'A'::TEXT AS type,
            primary_ip::TEXT AS content,
            0 AS ttl,
            NULL::INT AS prio,
            last_modified::TEXT AS change_date
        FROM nodes
            INNER JOIN object_properties ON id = object_id;
    </code>
    Результат:

    <code class="bash">$ nslookup 
    > ns
    Server:         10.1.1.1
    Address:        10.1.1.1#53
    
    Name:   ns.domain.local
    Address: 10.1.1.1
    </code>
    Обратную зону можно реализовать аналогично, а можно и немного интереснее. У любого хоста может быть несколько интерфейсов с разными адресами, поэтому имя, соответствующее адресу, можно составить из собственно имени хоста и имени интерфейса. Тогда последнее представление изменится следующим образом:

    <code class="sql">CREATE OR REPLACE VIEW domains AS
        SELECT
            0::INT AS id,
            'domain.local'::TEXT AS name,
            NULL::TEXT AS master,
            NULL::INT as last_check,
            'NATIVE'::TEXT as type,
            NULL::INT as notified_serial,
            NULL::TEXT as account;
    
    CREATE OR REPLACE VIEW records AS
        SELECT
            0::INT AS id,
            0 AS domain_id,
           'domain.local' AS name,
           'SOA'::TEXT AS type,
           'ns.domain.local'::TEXT AS content,
            0 AS ttl,
            NULL::INT AS prio,
            NULL::TEXT AS change_date
        UNION
        SELECT
            id,
            0 AS domain_id,
            LOWER(name) AS name,
            'A'::TEXT AS type,
            primary_ip::TEXT AS content,
            0 AS ttl,
            NULL::INT AS prio,
            last_modified::TEXT AS change_date
        FROM nodes
            INNER JOIN object_properties ON id = object_id
        UNION
        SELECT
            0::INT AS id,
            0 AS domain_id,
            'in-addr.arpa' AS name,
            'SOA'::TEXT AS type,
            'ns.domain.local'::TEXT AS content,
            0 AS ttl,
            NULL::INT AS prio,
            NULL::TEXT AS change_date
        UNION
        SELECT
            interfaces.id,
            0 AS domain_id,
            reverse_address(interfaces.ip_addr::INET) AS name,
            'PTR'::TEXT AS type,
            (object_properties.name||'.'||interfaces.description)::TEXT AS content,
            0 AS ttl,
            NULL::INT AS prio,
            last_modified::TEXT AS change_date
        FROM interfaces
            INNER JOIN nodes on nodes.id = interfaces.node_id
            INNER JOIN object_properties on nodes.id = object_id;
    </code>
    Результат:

    <code class="bash">$ nslookup 
    > 10.7.1.1
    Server:         10.1.1.1
    Address:        10.1.1.1#53
    
    1.1.1.10.in-addr.arpa   name = ns.eth0.
    </code>
    В коде упоминается функция reverse_address, ее реализация выглядит так:

    <code class="sql">CREATE OR REPLACE FUNCTION reverse_address(addr inet)
    RETURNS text 
    AS
    $t$
    DECLARE
        mask integer;
        parts text[];
        part text;
        retval text;
        rounds integer;
        host text;
    BEGIN
        retval := '';
        rounds := 0;
        mask := masklen(addr);
        host := host(addr);
        IF (family(addr) = 4) THEN
            IF (mask < 8) THEN
                rounds := 4;
            ELSIF (mask < 16) THEN
                rounds := 3;
            ELSIF (mask < 24) THEN
                rounds := 2;
            ELSIF (mask < 32) THEN
                rounds := 1;
            END IF;
            FOREACH part in ARRAY regexp_split_to_array(host, '\.') LOOP
                rounds := rounds + 1;
                IF (rounds <= 4) THEN
                    retval := part || '.' || retval;
                END IF;
            END LOOP;
            RETURN retval || 'in-addr.arpa';
        ELSE
            RETURN 'ip6.arpa';
        END IF;
    END;
    $t$
    LANGUAGE 'plpgsql'
    IMMUTABLE;
    </code>
    И это единственная часть реализации, специфичная для PostgreSQL. Все остальное можно сделать аналогичным образом на других СУБД, поддерживаемых NetXMS и PowerDNS.

    Напоследок о производительности: это решение, конечно, не годится для публичных DNS-серверов. Для внутреннего употребления — вполне. При первом выполнении все запросы укладываются в 100 msec, затем работает кэш. Есть поле для оптимизации с использованием параметров gpgsql-*-query вместо представлений, но пока нам хватает.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Из песочницы] Новые аргументы в битве с настройками Insyde UEFI BIOS

    Не так давно на Хабре была опубликована подробная статья о изменении скрытых настроек Insyde BIOS. Не претендуя на лавры её автора и всех остальных людей работавших над темой (модифицировавших grub UEFI shell и первопроходцев парсинга меню), хочу описать несколько проблем (и способов их решения) которые могут возникнуть у желающих применить эту информацию на практике:

    1. Невозможность получить расшифрованный дамп биоса
    2. Некорректная работа grub-шелла (зависание после выполнения setup_var)
    3. Невозможность изменить некоторые настройки
    Стоит заметить всеми этими проблемами я лично столкнулся (и потратил на них немало усилий) в попытках активировать для SATA контроллера RAID режим вместо AHCI (для последующего включения Intel SRT) на довольно свежем DTR ноутбуке HP Envy 17-j005tx (i7-4700MQ, 16gb, GT740M 2gb, 2x1000gb).

    Проблема 1: Невозможность получить расшифрованный дамп биоса

    И в статье на хабре и в другим местах интернета единственным упоминаемым способом получения дампа расшифрованного (если он не зашифрован на сайте производителя то и проблемы нет) биоса для последующей распаковки и парсинга меню является модификация файла platfCL_Prefix_orm.ini в папке прошивальшика.

    К сожалению на моем ноутбуке (и практически уверен что и на всех остальных новых моделях от HP) этот способ уже не работает — подозреваю что биос закрыли для чтения даже для собственного прошивальшика во избежание проблем в будущем. Все попытки изменения .ini файла и запуска прошивальника приводят к одному результату (что на оригинальной x64 Win 8, что из под PE x32/x64 дистрибутивов, т.е. проблема не в системе) — ошибке «IHSI: flash read error in SMI!» (для гугла). Кстати не пугайтесь, увидев такое перезагрузить ноутбук вы сможете только отключив питание и достав батарейку:



    Но, что важно, сама прошивка BIOS-а происходит (обычно) при этом не напрямую, а с использованием UEFI — т.е. прошивальшик передает образ BIOS UEFI утилите (как оказалось уже расшифрованный), и нам осталось лишь найти где он хранится. Возможно вы уже обращали внимание на несколько небольших дополнительных скрытых разделов на основном HDD/SSD (и это помимо довольно крупного (24 GB, с исходником win8) видимого Recovery раздела), в моем случае они типа Recovery Partition (400mb) и EFI System Partition (260mb, он то нам и нужен). Вот только беда — стандартным Disk Management вы этим разделам буквы не назначите — на то они и системные, впрочем гугл и командная строка нас как обычно спасают (выполнять обязательно из под аккаунта администратора, и лучше сразу из файлового менеджера, например незабвенного FAR):
    <code class="bash">mountvol X: /S
    </code>
    После этого открываем диск X:, и ищем что-нибудь похожее на BIOS. В моем случае все оказалось довольно прозаично и в папке X:\EFI\HP\BIOS нашлось три под-папки Current, New и Previous с искомым содержимым (01966.bin магический образованный прошивальшиком из 01966.fd). Дальше — все как в статье, распаковываем, парсим, и т.д.

    Напоследок замечу что в отличии от чтения прошивальшик не потерял возможность писать BIOS и напрямую даже из под Win8 x64. Узнал я об этом правда печальным способом, пытаясь прошить файлик из оригинального комплекта, но под другую платформу. Надо отдать должное HP — восстановление правильного биоса произошло в течении минуты (мне хватило поседеть ещё +1%) в полностью автоматическом режиме, правда одно последствие осталось — Win8 перестала загружаться в Secure Boot режиме.

    Проблема 2: Некорректная работа grub-шелла (зависание после выполнения setup_var)

    Узнав заветные адреса переменных которые вам нужно поменять, скопировав grub-шелл на флешку и удачно запустив его (все описано в статье) вы можете столкнутся с ещё одной проблемой — каждое выполнение setup_var (неважно на чтение или запись) будет приводить к зависанию ноутбука (в моем случае лечилось только извлечением батарейки). Причина была найдена только путем анализа исходника патча для добавления комманды setup_var в grub — банальный buffer oveflow. Автор писал утилиту под себя (свой лэптоп), и не рассчитывал что переменная Setup может иметь размер больше чем 0x2bc (а она читается целиком в память, и в моем случае составляла например 0x4ae байт). Можно сказать что всем удачно использовавшим утилиту на протяжении 4 лет довольно сильно повезло — с таким багом можно было получить намного больше проблем (например запись мусора в CMOS) чем просто зависание ноутбука.

    Для тех кому «ехать» (т.е. справится с проблемой): качаем пересобранную BootX64.EFI, кладем как обычно в EFI\boot\, используем команду setup_var как и в оригинальной версии. Для упорных бонус-трэк: дополнительная команда setup_var2 (меняет значение не только в переменной Setup, но и в переменной Custom, зачем чуть ниже) и lsefivar (выводит список всех доступных переменных, приостанавливать вывод можно break-ом).



    Наличие этих двух дополнительных команд объясняется просто: сражаясь с непокорным биосом я обнаружил наличие дополнительной переменной Custom с таким-же GUID и размером как и переменная Setup. Т.к. в тот момент мне не удавалось изменить значение одной опции (подробнее в третей части) — то была надежда чего-то достичь поменяв его в переменной Custom. Успехом эти усилия не увенчались, а команды пусть будут, на память.

    Не пугайтесь размеру .EFI образа (2.5mb) — мне было лениво выбирать необходимые grub, поэтому они там все — отсюда и размер.

    Для недоверчивых и просто любопытных инструкция как повторить мой путь, ну или собрать свой grub:
    1. Качаем исходники свежего grub2 (trunk на тот момент не собирался, я использовал grub-2.00+20130519).
    2. Применяем мой патч или фиксим и адаптируем авторский (смешно, но лично я около часа времени убил на проблему с grub: incompatible license, и даже гугл не помог — решается добавлением GRUB_MOD_LICENSE(«GPLv3+»); в исходник).
    3. Собираем EFI образ grub. Подробно описано здесь. Единственное замечание по grub-mkimage, правильная строчка (если включать все модули):
      <code class="bash">../grub-mkimage -d . -o bootx64.efi -O x86_64-efi -p /efi/boot `find *.mod | xargs | sed -e 's/\.mod//g'`
      </code>
    Упомяну ещё UEFI shell из проекта Tianocore (качать EFI 1.0 Shell Full или EDKII UEFI Shell 2.0, но первая версия у меня работала стабильнее) — весьма удобная штука, имеет доступ и к EFI и к файловой системе (необходимый диск находим проверяя с помощью ls по очереди fs0:, fs1:, и т.д.), может выполнять другие EFI приложения, а так же сохранять значения EFI переменных (самое для нас важное) с помощью команды dmpstore. Про её команды можно для завтравки почитать тут или тут, пример использования в наших целях (сохраняет целиком значение переменной Setup в fs1:\setup_dumps\dump1.bin):
    <code class="bash">fs1:
    cd setup_dumps
    dmpstore Setup -s dump1.bin
    </code>
    Только учитываете что в дамп переменной добавляется заголовок переменной длины, для Setup смещение относительно индексов из меню и команды setup_var составляет 0x28).

    Хочется добавить что BIOS на моем ноутбуке позволяет загружать не только файл BootX64.EFI из папки EFI\boot, но и любой .EFI файл из любой папки почти любого носителя (опция Boot from EFI file, спасибо HP). В принципе ту же функциональность можно получить использованием UEFI шелла и загрузкой остальных EFI приложений из него, но тем не менее.

    Проблема 3: Невозможность изменить некоторые настройки

    В процессе ваших попыток изменения скрытых настроек BIOS вы можете столкнутся с тем что самые необходимые вам настройки не будут менятся, возвращаясь в исходное состояние после перезагрузки (переинициализации BIOS). К сожалению вендоры могут добавлять в биос свой код, который будет проверять наличие оборудования, серийный номер, или ещё какие-либо параметры и в зависимости от этого автоматически восстанавливать настройки на исходные значения. Причем сделано это будет не назло нам (спрятаных из BIOS меню хватает для защиты от дурака), а просто для того чтобы использовать одну и ту же платформу и один и тот же BIOS для разных конфигураций ноутбуков. И если вы пытаетесь поменять эти настройки только для того чтобы выяснить сможет лишь ваш ноутбук работать с новым железом (скажем mSATA модуль) — то тогда возможно стоит рискнуть, купить и установить его. Возможно вам повезет и магические настройки сами появятся или изменятся, как по щучьему велению.

    Чтобы не быть голословным приведу свою историю: в моем случае такой злаполучной опцией стало 0x39 — HDC Configure As / AHCI / RAID, которую никакими усилиями не удавалось поменять на значение 0x2 (RAID). Нужно мне это было только по одной причине — чтобы добавив в ноутбук mSATA SSD модуль подключить его в качестве кэша в виде Intel SRT. При этом наличие mSATA разъема ни в спецификациях ни в сервисном мануале вообще не описано, лишь на одной сильно размытой картинке из манула есть что-то похожее, но чтобы к нему добраться нужно наполовину разобрать шасси (а не просто снять заднею крышку). Теперь вы наверное понимаете мои сомнения — нужно покупать не копеечный SSD (был выбран кстати Toshiba 128GB — THNSNH128GMCT, радующий тестами, и в последствии разбитый как 1/2 iSRT, 1/4 over provisioning, 1/6 volume), разбирать наполовину ноутбук (купленный фирмой неделю назад, т.е. почти наверняка теряя гарантию), и даже если повезет с разъемом, то не факт что когда-нибудь удастся включить опцию RAID в BIOS. Надежду давало лишь то, что в США HP позволяет выбирать конфигурацию таких ноутбуков (при этом все они используют один и тот же биос), в том числе и добавляя 24gb или 32gb SSD Cache, правда при этом ограничивая максимальный обьем памяти 8gb (зачем?). Результат сомнений ниже (разъем в зеленой рамке):



    Производитель (HP) не подвел, первое включение и магическая опция сразу обнаруживается на месте, там где её ещё несколько минут назад не было (т.е. несколько дней неторопливой возни c setup_var на смарку):





    Напоследок хочу ещё заметить радостное — в отличии от всех описаний в интернете, Windows 8 вообще не заметила изменение AHCI режима на RAID, лишь в Device manager контроллер поменял название с SATA AHCI Controller на SATA RAID Controller. Заслуга это GPT, самой Windows 8, или Intel — не знаю, и не очень задаюсь этим вопросом — просто наслаждаюсь преобразившейся (без какого либо геморроя) скоростью работы системы.

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Из песочницы] Singleton serialization или сад камней

    image

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

    Но зачем городить огород сад?
    Первый логичный вопрос: если так проблем то зачем это вообще нужно? Такая хитрость, действительно, требуется не часто. Хотя многие люди, только начинающие работу с WPF или WinForms, пытаются реализовать таким образом файл с настройками приложения. Пожалуйста, не тратьте свое время и не изобретайте велосипед: для этого есть Application и User Settings (почитать про это можно здесь и здесь). Вот примеры, когда сериализация может потребоваться:
    Хочется передать синглтон по сети или между AppDomain. К примеру, клиент и сервер одновременно работают с одним и тем же ftp и синхронизируют свои сведения о нем. Информацию об ftp можно хранить в синглтоне (и там же пристроить методы для работы с ним).
    Сериализуется класс, которой присваивается различным элементам, но значение должно быть одинаковым для всех. Примером такого класса может являться DBNull.
    Синглтон
    В качестве несложного примера возьмем такой синглтон:
    <code class="cs">public sealed class Settings : ISerializable
    {
        private static readonly Settings Inst = new Settings();
        private Settings()
        {
        }
    
        public static Settings Instance
        {
            get { return Inst; }
        }
    
    
        public String ServerAddress
        {
            get { return _servAddr; }
            set { _servAddr = value; }
        }
    
        public String Port
        {
            get { return _port; }
            set { _port = value; }
        }
        private String _port = "";
    }
    </code>
    Сразу сделаю несколько комментариев по коду:
    • Намерено отсутствуют ленивые вычисления, чтобы не усложнять код.
    • Свойства не могут быть сделаны автоматическими, т.к. имена скрытых полей класса генерируются снова при каждой компиляции, и однажды честно сериализованный объект может уже не десериализоваться по причине различия этих имен.
    Первый взгляд
    В простых случаях для сериализации в C# хватает добавить атрибут Serializable. Что ж, не будем сильно задумываться на сколько наш случай сложен и добавим этот атрибут. Теперь попробуем сериализовать наш синглтон в трех вариантах: SOAP, Binary и обычныйXML.
    Для примера сериализуем и десериализуем бинарно (остальные способы аналогичны):
    <code class="cs">using (var mem = new MemoryStream())
    {
        var serializer = new BinaryFormatter();
        serializer.Serialize(mem, Settings.Instance);
        mem.Seek(0, SeekOrigin.Begin);
        object o = serializer.Deserialize(mem);
        Console.WriteLine((Settings)o == Settings.Instance);
    }
    </code>

    (Не)ожиданно на консоль будет выведено false, а это значит, что мы получили два объекта-синглтона. Такой результат можно предвидеть, если вспомнить, что в процессе десериализации с помощью рефлексии вызывается приватный конструктор и все десериализуемые значения присваиваются новому объекту. Именно эта особенность синглтона кладет первый камень в наш сад: синглтон перестает быть синглтоном.

    Усложняем и… кладем еще каменей.
    Так как не получилось сделать все просто, придется усложнить Если обратимся к более “ручному” процессу сериализации через интерфейс ISerializable, то на первый взгляд выгоды кажется никакой: прошлая беда не исчезла, а сложность возросла. Поэтому для дальнейшей действий нам еще потребуется достаточно редко используемый интерфейс IObjectReference. Все что он делает: показывает что объект класса, реализующего этот интерфейс, указывает на другой объект. Звучит странно, не правда ли? Но нам нужна другая особенность: после десериализации такого объекта будет возвращен указатель не на него самого, а на тот объект, на который он указывает. В нашем случае логично было бы возвращать указатель на синглтон. Класс будет выглядеть так:
    <code class="cs">[Serializable]
    internal sealed class SettingsSerializationHelper : IObjectReference 
    {
        public Object GetRealObject(StreamingContext context) 
        {
            return Settings.Instance;
        }
    }
    </code>
    Теперь мы можем сериализовывать объект класса SettingsSerializationHelper, а при десериализации получать Settings.Instance. Правда здесь есть два еще два камня:
    • Перед тем как сериализовать синглтон требуется создать объект другого класса.
    • Поля синглтона по-прежнему не сериализуются.
    Рассмотрим первый камень, который не очень критичен, но явно не приятен. Решение проблемы заключено в подмене класса для сериализации внутри GetObjectData. Выглядеть это будет так (внутри синглтона):
    <code class="cs">public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.SetType(typeof(SettingsSerializationHelper));
    }
    </code>
    Теперь когда мы будем сериализовывать синглтон вместо него будет сохранен объект SettingsSerializationHelper, а при десериализации мы получим обратно наш синглтон. Проверив вывод на консоль из ранее описанного примера сериализации, мы увидим, что в случае с Binary и SOAP будет выведено на консоль true, но для XML сериализации — false. Следовательно, XMLSerializer не вызывает GetObjectData и просто самостоятельно обрабатывает все public поля/свойства.

    Грязные хаки
    Проблема с сериализацией полей — самый крупный камень в нашем саду. К сожалению, мне не удалось найти совсем элегантное и честное решение, но получилось соорудить не очень честный, достаточно гибкий “хак”.
    Для начала в методе GetObjectData добавим сохранение полей синглтона. Выглядеть это будет так:
    <code class="cs">public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.SetType(typeof(SettignsSerializeHelper));
        info.AddValue("_servAddr", ServerAddressr);
        info.AddValue("_port", Port);
    }
    </code>
    Если теперь сделать SOAP сериализацию, то можно увидеть, что все поля действительно сериализованны. Однако в действительности мы сериализовывали SettignsSerializationHelper, у которого эти поля отсутствуют, а значит при десериализации у возникнут проблемы. Есть два пути решения:
    • Полностью повторить все поля синглтона в SettignsSerializationHelper. Такую подмену десериализатор вполне скушает, заполнит все поля, а внутри метода GetRealObject их надо обратно присвоить синглтону. У такого подхода есть один большой и серьёзный недостаток: ручная поддержка дублирования полей, их добавление для сериализации и десериализации. Это явно не наш бро выбор.
    • Призвать на помощь рефлексию, суррогатный селектор и чуточку linq, чтобы все было сделано за нас. Рассмотрим это подробнее.
    В начале изменим метод GetObjectData:
    <code class="cs">public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.SetType(typeof (SettignsSerializeHelper));
        var fields = from field in typeof (Settings).GetFields(BindingFlags.Instance |
                        BindingFlags.NonPublic | BindingFlags.Public)
                        where field.GetCustomAttribute(typeof (NonSerializedAttribute)) == null
                        select field;
        foreach (var field in fields)
        {
            info.AddValue(field.Name, field.GetValue(Settings.Instance));
        }
    }
    </code>
    Отлично, теперь когда мы захотим добавить поле в синглтон оно будет тоже сериалзованно без работы руками. Перейдем к десериализации.
    Все поля синглтона должны быть повторены в SettignsSerializationHelper, но для того, чтобы избежать их реального дублирования, применим суррогатный селектор и изменим SettignsSerializationHelper.
    Новый SettignsSerializationHelper:
    <code class="cs">[Serializable]
    internal sealed class SettignsSerializeHelper : IObjectReference
    {
        public readonly Dictionary<String, object> infos = 
                (from field in typeof (Settings).GetFields(BindingFlags.Instance 
                 | BindingFlags.NonPublic | BindingFlags.Public) 
                 where field.GetCustomAttribute(typeof (NonSerializedAttribute)) == null
                 select field).ToDictionary(x => x.Name, x => new object());
    
        public object GetRealObject(StreamingContext context)
        {
            foreach (var info in infos)
            {
                typeof (Settings).GetField(info.Key, BindingFlags.Instance |  BindingFlags.NonPublic 
                                               | BindingFlags.Public).SetValue(Settings.Instance, info.Value);
            }
            return Settings.Instance;
        }
    }
    </code>
    И так, внутри SettignsSerializationHelper создается хэш-мап, где key — имена сериализуемых полей, а value в будущем станут значениями этих полей после десериалазации. Здесь для большей инкапсуляции можно сделать infos как private и написать метод для доступка к его key-value парам, но мы не будем усложнять пример. Внутри GetRealObject мы устанавливаем синглтону его десериализованные значения полей и возвращаем ссылку на него.
    Теперь осталось только заполнить infos значениями полей. Для этого будет использован селектор.
    <code class="cs">internal sealed class SettingsSurrogate : ISerializationSurrogate
    {
        public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
        {
            throw new NotImplementedException();
        }
        public object SetObjectData(object obj, SerializationInfo info, StreamingContext context,
                                    ISurrogateSelector selector)
        {
            var ssh = new SettignsSerializeHelper();
            foreach (var val in info)
            {
                ssh.infos[val.Name] = val.Value;
            }
            return ssh;
        }
    }
    </code>
    Так как селектор будет использоваться только для десериализации, то мы напишем только SetObjectData. Когда obj (десериализуемый объект) приходит внутрь селектора, его поля заполнены 0 и null не зависимо от обстоятельств (obj получается после вызова в процессе десериализации метода GetUninitializedObject из FCL_Prefix_ormatterServices). Поэтому в нашем случае проще создать новый SettignsSerializationHelper и вернуть его (этот объект будет считаться десериализованным). Далее, внутри foreach заполняем infos десериализованными данными, которые потом будут присвоены полям синглтона.
    И теперь пример самого процесса сериализации/десериализации:
    <code class="cs">И теперь пример самого процесса сериализации/десериализации:
    using (var mem = new MemoryStream())
    {
        var soapSer = new SoapFormatter();
        soapSer.Serialize(mem, Settings.Instance);
        var ss = new SurrogateSelector();
        ss.AddSurrogate(typeof(SettignsSerializeHelper),
        soapSer.Context, new SettingsSurrogate());
        soapSer.SurrogateSelector = ss;
        mem.Seek(0, SeekOrigin.Begin);
        var o = soapSer.Deserialize(mem);
        Console.WriteLine((Settings)o == Settings.Instance);
    }
    </code>
    На консоль будет выведено true и все поля будут восстановлены. Наконец, мы закончили и привели наш сад камней в должный вид.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Elance – мошенники?

    Возможно, заголовок звучит немного желтовато, но в моей голове сейчас вертится именно эта мысль, и вот что привело меня к ней:
    Прочитав, не так давно, очередной пост на Хабре с упоминанием этой биржи фриланса я решил посмотреть, что там к чему. Зарегистрировался и начал просматривать предложения в поисках чего-то интересного. Спустя несколько дней подвернулся заказчик, с которым мы договорились и начали работать. Обьём работ быль довольно большим, оплата была хорошей. Так как и я, и заказчик не имели никаких отзывов на Elance, то для подстраховки нас обоих начали работу частями с оплатой через Elance Escrow. Заказчик переводит часть суммы елансу, который удерживает её до тех пор, пока я не выполню оговорённую часть работы. Как только заказчик доволен данным этапом он «отпускает» деньги и они попадают на мой счёт на Elance и мы приступаем к следующему пункту по той же схеме.

    Получив первый транш я, конечно же, захотел сразу вывести деньги, но перед этим Elance запросил подтверждения номера телефона, для чего на телефон звонит робот и ему нужно продиктовать или набрать на клавиатуре телефона номер, указанный на странице вашего профиля. С первой попыткой что-то не получилось, мне никто не позвонил, а на странице на два дня повисло сообщение «Ждите звонка». После обращения в службу поддержки мне снова стал доступен запрос звонка, и со второй попытки всё прошло гладко. Спустя ещё несколько дней первая часть денег уже была на моём счету, а я думал, что всё самое сложное уже позади.

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

    Для проверочного звонка по скайпу можно выбрать подходящее для вас время из предложенных вариантов. Я выбрал промежуток с 17.00 до 18.00 вторника. Жена с ребёнком ушли гулять, а я стал ожидать звонка занимая себя всякими домашними делами. И вот, в 17.55 мне, наконец, написали в скайпе что сейчас позвонят и сделаю фотографию, поэтому, нужно ответить с включённой камерой. Позвонили, я принял звонок, посмотрел секунд 10 в камеру и с той стороны трубку положили. Через несколько минут ко мне на почту пришло письмо, что проверка пройдена, о чём я незамедлительно сообщил саппорту и попросил возобновить процедуру вывода денег.

    На следующий день я решил проверить как дела и что нового на Elance, но не смог залогинится. На все попытки я получал сообщение вида:
    «Your Elance account is expired.»
    Ну, мало ли, может ошибка на сайте, подумал я, попробую через пару часиков. Но, через несколько часов ничего не изменилось. Как то я начал немного волноваться и решил обратится в саппорт. Описал проблему в форме на сайте и стал ждать ответа. Вопрос с проблемой во время проверки номера телефона решился довольно быстро, так что и тут я ждал быстрого ответа, но прошло больше 24 часов а я так и не получил ответного письма. Тут я начал волноваться уже посерьёзней и решил написать в саппорт ещё раз, уже без сайта, просто на email адрес службы поддержки. И …. Я снова не получил никакого ответа.

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

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

    P.S.
    Получил ответ от саппорта:
    Our risk management system has detected irregularities with your account.

    Because of this, we are closing your Elance account, effective immediately. Needless to say, we don't take this decision lightly and have reviewed your account in detail before taking this action.

    To view our Terms and Conditions, please go to:
    www.elance.com/p/help/tos/index.html


    И это всё, без каких либо объяснений, какие именно правила были нарушены, и без возможности исправить/оправдаться.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Новое для веб-дизайнера #7

    Новые полезные инструменты, сервисы, бесплатные плюшки для веб-дизайнеров и веб-разработчиков за первую половину августа 2013. Остальные подборки доступны по тегу "новое для веб-дизайнера".

    Полезные сервисы

    Responsive Web CSS — сервис для быстрого и удобного создания файлов CSS при разработке адаптивного сайта:

    image

    WakaTi.me — отличный сервис для ведения логов работы в текстовом редакторе. Поддерживаются SublimeText, Vim:

    image

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

    image

    MockupPhone помогает в один клик «обернуть» любой скриншот в мокап iOS или Android девайса:

    image

    Long Shadow Generator — генератор столь популярных в последнее время длинных теней:

    image

    Buttons — быстрое создание простых и приятных кнопочек.

    image

    Бесплатные плюшки

    Responsive Nav — отличный для создания адаптивной навигации. Подкупает простотой и лаконичностью:

    image

    Precomposed Touch Gestures — здесь можно скачать видеоанимацию всех жестов для тачскрина, файлы в формате mov, поэтому работают в любом видеоредакторе и Фотошопе:

    image

    Flattastic UI kit — отличный набор элементов интерфейса:

    image

    48 иконок для дизайнера в стиле flat:

    image

    Интересное

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

    image

    Советы от веб-дизайнеров со всего мира в виде чек-листов:

    image

    Devs Do Art — бытовое искусство от веб-разработчиков:

    image

    The Pronunciation of European Typefaces — как понятно из названия, в этой статье Ральфа Хермана (Ralf Herrmann) собраны правильные произношения названий многих шрифтов. Очень познавательно.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Сверхбыстрое копирование\вставка фрагментов кода

    Постоянно программируя на C++/Qt, я заметил, что было бы удобнее хранить где-нибудь свои отрывки кода и иметь к ним быстрый доступ. Конечно же, я принялся искать и нашёл множество готовых программ-органайзеров и сайтов. Я перепробовал их, но меня всё это не устроило.

    Хотелось именно быстрого доступа — а значит по глобальным хоткеям. Чтобы нажал — ввёл слова в поиск — получил код. Но такими функциями обладали всего две программы, а они были платными и не кроссплатформенными.

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


    История разработкиДля начала я решил — программа должна быть, маленькой, удобной и шустрой. А значит — следует поместить программу в трее, чтобы не мешалась на панели задач. Благо что Qt предоставляет для этого удобное кроссплатформенное решение в виде класса QSystemTrayIcon. Также программа должна обязательно работать на глобальных хоткеях. Вот тут возникла проблема! Дело в том, что Qt, к сожалению, из коробки не поддерживает их. На то есть библиотека libqxt, которую я весьма успешно использовал почти год под Qt 4.8. Однако под Qt 5 её по неясной мне причине ещё нормально не доработали (на тот момент) и под Win7 она собираться ну никак не хотела — и я бросил эту затею. Вместо этого вставил самую капельку нативного кода — вызов winApi функции RegisterHotKey. Это единственная нативная вставка в программе — и я думаю что будет совсем легко доработать её под Linux или Mac.

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

    В качестве основы для редактора я взял, конечно же, QTextEdit. Тут меня ждал приятный сюрприз — код, скопированный из QtCreator — копируется как HTML с разметкой, а следовательно — с подсветкой синтаксиса. Тут же необходимость писать встроенную подсветку синтаксиса для C++\Qt отпала сама по себе. QtCreator имеет очень крутую подсветку синтаксиса, особенно если её настроить под себя.

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

    Также сделал кейворды. Ну как же без них? Поиск идёт не только по основному коду, но и по ним тоже. В кеях можно указать языки программирования, к которым относится данная паста, например «c++,qt» или «qml,js». Если в результате поиска появились фрагменты кода из нескольких языков, можно дифференцировать их, добавив ключевое слово-язык.

    Дорабатывая программу, нарисовал в GIMPe логотип — фигурные скобочки. Просто и понятно.

    Обзор программыМожете скачать Windows-дистрибутив программы здесь или собрать её из исходников, скачав их с github. Только распаковывайте их не на рабочий стол, как это делают многие. Дистрибутив вместе со всеми dll весит 16 МБ в запакованном виде и 40 в распакованном — Qt5 значительно разжирел и даже простейшая программа требует тащить за собой целую массу библиотек. Но я думаю что это не проблема, тем более что оно никак не сказывается на скорости работы программы.

    Распакуйте программу в любую папку на диске и запустите. Она создаст в своей папке файл конфигурации config.xml, а потом, при сохранении, чистую базу данных для вашего кода base.xml. Собственно как выглядит главное меню — вы можете увидеть на скрине в заголовке статьи. Интерфейс программы пока что весь на английском, чтобы не было проблем со сборкой на некоторых системах — сообщения и подписи пока-что в исходниках.

    Добавление нового фрагмента кода осуществляется по глобальному хоткею ctrl+D, а поиск — по win + V. Вы можете бросить в меня камень за такие «глобальные» хоткеи, но эксперименты показали что они самые удобные. Да, возможно вы привыкли по ctrl+D отправлять код из QtCreator куда-либо. Если это так критично, можете зайти в конструктор класса CodePaster и поменять там хоткеи на те, которые вам угодны. В дальнейшем это можно будет сделать через GUI.

    Продолжим. Допустим, вы написали какой-то удобный алгоритм, или освоили новую конструкцию языка, которую нет желания печатать каждый раз. Вы просто выделяете ваш блок кода в вашей любимой (например в креэйторе) — и копируете как обычно через ctrl+C. Тут же будет удобно и совсем рядом — не отпуская ctrl — нажать на D. Вылезет окно поверх вашей IDE — и код уже сам прыгнет в него! Программа в автоматическом режиме читает буфер обмена, вставляя из него код. Ещё тут есть ещё 2 небольшие фичи — вставляется подпись перед кодом в виде комментария "//", а также у самого кода убираются лишние отступы. Т.е. если вы скопировали его из середины программы, то он сдвинется влево до упора.

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

    Далее — когда вам захотелось быстро скопировать этот код — нажимаете win + ctrl. Почему именно его? Мне он кажется удобным вариантом и нигде не задействован. Вы увидите маленький поисковик по коду, и уже оттуда сможете скопировать нужные вам фрагменты. Что касается самого поисковика — то у каждого куска кода есть контекстное меню. Вы можете удалить его из базы, можете отредактировать, а можете посмотреть его свойства.


    Как видите, фрагменты кода разделяются через "---", у каждого есть свой id, а также мелкие плюшки — программа запоминает дату добавления и сколько раз он был скопирован.

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

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

    ПримерыПриведём простой пример использования программы — если вам вдруг понадобилось кинуть в вашей программе мессаджбокс для отладки (именно его, а не вывод qDebug) — заранее подготовив код, вы просто набираете win + V и вбиваете «mes» — этого достаточно, чтобы найти нужный кусок кода и скопировать его. Вы потратите одно нажатие хоткеев, набор 3 символов, Enter (который в дальнейшем можно будет убрать), и выделение-копирование. А теперь дайте сравним — сколько времени вы потратите, чтобы скопировать его из того же ассистанта? Даже если он на глобальном хоткее — вам придётся через выделение или клавиш получить фокус для строки поиска, ввести туда «mess», выбрать нужный класс мышкой (!), промотать вниз до того места где есть пример (если он есть) и только тогда скопировать его. Это как минимум в 2 раза дольше. Qt Assistant — это просто идеальная документация, однако для копирования-вставки постоянно используемых кусков кода он не подходит.

    Какие варианты вы ещё предложите? Заходить каждый раз на сайт pastebin и искать там? Это тоже лишние задержки. Вводить в гугле по 100 раз одни и те же запросы? А ведь большинство программистов, с которыми я общался на эту тему — так и делали — они каждый раз всё гуглили. Но ведь один раз нашёл — можно сохранить в какой-нибудь «кэш» для быстрого доступа, изменив если надо — и использовать на здоровье! Этим кэшем и должна быть программа, хорошо интегрированная с системой для большего удобства.

    Приведём другой пример. Я часто сижу на форуме prog.org.ru и постоянно нахожу или получаю много хороших решений разных небольших задач. Например, как с помощью QSettings добавить программу в автозагрузку Windows. Или как динамически подгрузить ui-форму. Там целые алгоритмы. Каждый раз искать то нашёл один раз — это не комфортно. Хорошие и красивые решения приятно сохранять для себя для будущего использования.

    Ещё один пример — я один раз сохранил код для bat-файла, который добавляет переменную в windows environment variables. Когда он бывает нужен — просто копирую его в командную строку вместо использования неудобного GUI.

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

    Если вы работаете сразу с несколькими языками программирования — преимущества использования такой программы станут ещё более существенными. Вы можете забыть как выглядит та или иная конструкция на определённом языке — и через поиск легко вспомнить.

    Обзор исходного кодаИсходный код я писал жёстко по стандарту Qt Coding Style. Временами использовал конструкции С++11. Я думаю при его чтении проблем не возникнет. Все окна построены на основе виджетов, однако потом планирую перевести их на QML.

    Вообще — не судите строго. Это мой первый публичный проект и я надеюсь что хоть кому-то пригодится если не прога, то те моменты, которые я изложил здесь. Если прога окажется реально полезной и вы плюсуете — то могу её доработать. В планах — сделать её ещё удобнее (идеи есть), подсветку синтаксиса для других языков и поддержку хоткеев для Linux\Mac.

    Также не исключаю, то что где-то в статье или в коде есть опечатки и\или ошибки. Рад буду принять здавую критику.

    Так что — жду ваших отзывов!

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Почему балансирует бухгалтерский баланс?

    image

    Если вам известно, что такое бухгалтерский баланс, можете закончить чтение на этом. Если же баланс ускользнул от внимания, тогда, возможно, вас заинтересует его нехитрое, вместе с тем неординарное устройство.

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

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

    Ну регистрирует и регистрирует, при чем здесь баланс? При том, что вещи поступают на предприятие и выбывают с него, тем самым регистрация вещи осуществляется дважды: по приходу и расходу. У каждой регистрируемой в бухгалтерии вещи имеется приход – момент поступления на предприятие (условный +), и расход – момент выбытия с предприятия (условный –).

    image

    В общем случае приход одной вещи соседствует с расходом другой. Это обусловлено одной из двух причин:
    • либо законом сохранения материи (применительно к бухгалтерии случаем, когда вещь переименовывается в связи с изменением характеристик, при этом считается, что одна вещь выбыла, а другая взамен нее поступила),
    • либо торговым обменом, когда одна вещь обменивается на другую де-факто.

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

    image

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

    image

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

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

    image

    Обозначим список таких вещей графически, в виде списка.

    image

    Какой здесь – в простом списке вещей, удовлетворяющих некоторым условиям, – может быть баланс? Никакого, разумеется.

    Но погодите.

    В хозяйственной деятельности учитываются не только наличные вещи, то есть инвентарь, но и вещи будущие, поступление которых ожидается, – допустим, в связи с заключенным договором. Формальное отличие от инвентаря: регистрация не текущего поступления, а будущего, – наличная вещь (инвентарь) уже поступила, а будущая вещь только ожидается к поступлению, но все равно регистрируется.

    image

    Правда, имеется одна тонкость, и существенная. Бухгалтерия не умеет регистрировать объекты будущей датой: в рамках одной бухгалтерской записи-проводки дата должна быть одна – текущая. Поэтому вместо будущего прихода объекта регистрируется текущее обязательство.

    image

    Инвентарь – то, что предприятие имеет, а дебиторское обязательство, или попросту дебиторка – то, что предприятие должно получить. Такого объекта как дебиторка в природе не существует, однако под ней подразумевается вполне себе существующая вещь, которая в соответствии с юридическими нормами должна поступить на предприятие (в будущем).

    Понятное дело, одно должно быть отделено от другого.

    image

    Почему дебиторка, а не просто обязательства? Потому что помимо дебиторки существует еще кредиторка – кредиторские обязательства: то, что предприятие в соответствии с юридическими нормами должно отдать.

    По сути, это будущий расход объекта.

    image

    Но в связи с названными выше обстоятельствами регистрируется не будущий расход объекта, а обязательство – на этот раз кредиторское.

    image

    Смотрите, что получается: нормальные вещи всегда сначала регистрируются сначала по приходу, затем по расходу, а кредиторка – сначала по расходу, затем по приходу. Все невозможности регистрировать два объекта одной бухгалтерской проводки разными датами, вследствие чего приходится регистрировать не будущий расход реального объекта, а некое не существующее в действительности обязательство. Вот к каким незаурядным последствиям приводят ошибки в учетной методологии!

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

    image

    Ответьте, присутствует здесь баланс (равенство между двумя колонками – положительной и отрицательной)? Не присутствует и присутствовать не может.

    В рамках отдельного предприятия три рассмотренных типа объектов никак между собой не коррелируют. Соотношение может быть любым – таким, к примеру (благоприятным):

    image

    Или таким (менее благоприятным):

    image

    Или даже таким (что означает: предприятие – фактический банкрот, поскольку, даже распродав все имущество и сполна получив от должников, не сможет расплатиться с кредиторами):

    image

    Если равенство положительной и отрицательной колонок и имеет место, то это чистая случайность, никак не закономерность.

    Нет баланса, короче. Но конечно, только в рамках одного предприятия. Если все балансы всех предприятий и физических лиц совместить в одном балансе (как говорят в бухгалтерии, консолидировать), то получится… что, по-вашему? Баланс, в котором имеется один инвентарь.

    Дебиторка и кредиторка – величины равные и противоположные по знаку: если кто-то должен отдать, то кто-то должен и получить, причем ровно столько же. Значит, при консолидации балансов всех участников хозяйственной деятельности в один баланс дебиторка и кредиторка окажутся зачтены в качестве долгов самому себе, в результате чего останется инвентарь – все задействованное в хозяйственной деятельности человечества имущество. Что предполагалось изначально, когда мы взялись составить баланс, единый для всех участвующих в хозяйственной деятельности лиц.

    image

    Вот еще любопытная, чисто бухгалтерская фича.

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

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

    image

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

    image

    Во как: холодильник один, но регистрируется два объекта, один положительный (по приходу), второй отрицательный (по расходу)!

    Но хватит о поэтическом, вернемся к бухгалтерскому балансу, до которого непонятно как добраться. Как было сказано, баланса нет и не предвидится – имеются две противоположные по знаку, но категорически отказывающиеся уравниваться колонки:

    image

    Откуда же берется баланс?

    Вы не поверите: он создается искусственно. Недостающая часть, под названием капитала, помещается в меньшую колонку – и дело в шляпе.

    image

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

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

    Допустим, вещь испортилась, пришлось ее выбросить. Имеет место, с одной стороны, уменьшение инвентаря, а с другой стороны… как ни крути, вторая вещь отсутствует.

    Вторая вещь отсутствует в природе и хозяйственной практике, но только не в бухгалтерии, в которой регистрируется подставной объект под названием капитал: подставной – потому что просто подставляется взамен отсутствующего объекта, и все. Поскольку суммы по приходу и расходу (дебету и кредиту) бухгалтерской проводки всегда равны, возникает баланс положительной и отрицательной колонок, с самой первой бухгалтерской проводки, какой бы она ни была. Допустим, с такой:

    image

    Никакие последующие изменения не могут данный баланс поколебать, поскольку воздействуют на колонки баланса всегда равнозначно:
    либо уменьшают и одновременно увеличивают одну из колонок (такие изменения называются пермутациями);

    image

    либо равнозначно уменьшают или увеличивают одновременно обе колонки (такие изменения баланса называются модификациями).

    image

    Как вы понимаете, равенство сохраняется за счет того, что колонки баланса имеют разные знаки.

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

    Лишь одна цитата, известного в начале прошлого века Г.А. Бахчисарайцева:

    «Тут поразительное отсутствие всякого здравого смысла. Еще удивительнее то, что «разнеся» обороты по закону двойной записи, эти бухгалтера получают равные итоги по «Дебету» и «Кредиту» счетов и восторгаются, заявляя: «Вот еще один основной закон бухгалтерии! Итог левых сторон равен итогу правых сторон» (счетов). И этот «самостоятельный» (!), с их, конечно, точки зрения, закон они называют «законом Баланса» или «законом Баланса счетов». Может ли быть что-нибудь наивнее! К двум равным величинам прибавить поровну, получить в итоге поровну и… кричать: «основной закон счетоводства – закон Баланса, как следствие (?!) закона двойной записи»! Господа! математика подобные истины называет просто «аксиомами», и вы напрасно увлекаетесь (и других увлекаете) своими краткохвостыми законами».

    Справедливости ради стоит заметить, что существуют десятки т.н. счетных теорий, пытающихся обосновать существование бухгалтерского баланса в качестве объективного феномена. Нет смысла обсуждать их с неспециалистами, поскольку «объективность» бухгалтерского баланса очевидна. Кто-нибудь сомневается в том, что, в случае официальной отмены бухгалтерского баланса предприниматели прекратят им пользоваться?

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

    image

    Такова форма объективного, а не надуманного баланса. Но конечно, именовать данную отчетную форму балансом окажется уже невозможным.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Как uLogin забыл продлить домен и что из этого получилось

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





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

    Очевидно, что будет дальше: команда напишет извинения, домен будет спешно оплачен, многие будут решать для себя, хотят ли они дальше использовать uLogin или нет. А применяли его отнюдь не только любительские проекты, но и достаточно серьёзные — например, наш партнёр рекламная сеть AdEasy, через которую Roem.ru продаёт часть рекламы.

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

    Вот весь список:
    1. Сторонний CDN для статики
    2. Рекламная крутилка AdFox
    3. Счётчик Liveinternet
    4. Rambler Top100
    5. «Яндекс.Метрика
    6. Кнопки соцсетей: ВКонтакте
    7. Facebook
    8. twitter
    9. »Мой Мир"
    10. «Одноклассники»
    По сути, проблемы любого из этих сайтов, лишают наш проект части работоспособности. Думаю, что мы посмотрим на трафик и пользу, которую приносят нам эти сервисы и от части из них в итоге откажемся — ведь использование лишних 10 кодов означает то, что отказоустойчивость системы в целом снижается на порядок.

    Отдельный вопрос: почему в Рунете нельзя продлевать домен больше чем на год? Большая часть проблем этим решалась бы


    Вы хотели бы продлевать домен больше чем на год?


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 329 человек. Воздержалось 58 человек. Сколько сторонних кодов вы используетей на своём сайте



    Да



    Нет


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 283 человека. Воздержалось 77 человек. Источник: habrahabr.ru,
    получено с помощью rss-farm.ru




    Не использую



    1-5



    Больше пяти

    [recovery mode] Удобный интерфейс Хабра? Легко!

    Добрый день, после прочтения этого топика я твердо решил освоить написание расширений для Google Chrome.
    Не люблю длинные речи, потому встречайте:
    ХабраРедизайнер alpha делает шапку сайта похожей на концепты grokru.



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



    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Первая квантовая телепортация информации на компьютерном чипе

    Физики из Швейцарской высшей технической школы Цюриха (ETH Zurich) впервые в мире осуществили квантовую телепортацию квантовых битов информации с одного участка кремниевой микросхемы в другое место на той же микросхеме, на расстояние 6 мм. При этом они ещё и поставили мировой рекорд по количеству телепортированных кубитов: 10 000 в секунду.

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


    Диаграмма квантовой телепортации (ETH Zurich)

    Для эксперимента использовали микросхему размером 7х7 мм, которую охладили до сверхпроводящего состояния, то есть до температуры, близкой к абсолютному нулю. На микросхеме было три цепи, не соединённых друг с другом (Q1, Q2 и Q3, на диаграмме). Две из них использовали для генерации и отправки кубитов, а третью — для приёма.

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

    Авторы эксперимента говорят, что их метод квантовой телепортации отличается от аналогичных разработок других учёных своей надёжностью. Если раньше демонстрировалась передача информации с маленькой вероятностью, то новый метод работает гораздо более точно. На диаграмме показаны реальные (синим) и мнимые (красным) реконструированные матрицы плотности для выходного состояния |?out), измеренные с помощью томографии а) после выбора данных с результатом 00 измерения Белла; б) используя усреднённые считывания в точке Q3 при выполнении полностью предсказуемой телепортации с опережением. Идеально ожидаемые значения обозначены рамками на столбцах. Точность состояния обозначена цифрами в чёрных полях (источник).



    Информация о научном эксперименте опубликована в журнале Nature (doi:10.1038/nature12422).

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Square Enix запретила художнику продавать отпечатанные 3D-фигурки персонажей Final Fantasy VII



    На днях в СМИ появилась новость об очередном инциденте с нарушением авторских прав, который не очень похож на все прочие ситуации с копирайтом. Обычно речь идет о «пиратах», которые скачивают или загружают что-либо, или распространяют нелегальное ПО на носителях, что-то в этом роде. Нынешний случай уже выходит из привычных нам границ. В общем, к делу. Есть художник, Хоакин Болдуин (Joaquin Baldwin), которому очень нравится серия Final Fantasy, включая Final Fantasy VII. Этот художник решил совместить приятное с полезным, и открыть магазинчик по продаже фигурок героев Final Fantasy VII (фигурки он печатает на 3D принтере).

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

    Конечно, по закону Square Enix имеет все основания для предъявления таких требований, тем более, что фактуры главных героев были получены Хоакином непосредственно из ПК-версии игры. Также Хоакин не обращался к Square Enix за лицензией на печать фигурок. Но как-то сомнительно, что подобная деятельность может повредить финансовому состоянию указанной компании, или нанести ущерб ее репутации.

    Возможно, ничего подобного и не случилось бы, однако Square Enix очень активно охраняет собственные права, особенно те из них, что касаются серии Final Fantasy. Так, в этом году этот же издатель закрыл кампанию на Kicktarter, цель которой была собрать деньги на создание неофициальной версии FFVII. В прошлом году была закрыта еще одна кампания на Kicktarter, имеющая отношение к той же игре.

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

    theverge

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Из песочницы] Скажем нет форматированию пробелами и энтерами

    Знакомство каждого человека с компьютером рано или поздно подходит к редактированию документов.
    А вот дальше, как говориться, есть варианты.


    Человек может использовать компьютер лишь как печатающую машинку, у которой все средства форматирования сводятся к вставке лишних пробелов да переводу каретки на нужный интервал.
    А может и научиться правильно форматировать документ используя хотя-бы необходимый минимум пробелов функциональности редактора.

    Вот те, кому надоело видеть/выковыривать из текста лишние пробелы, кому необходимо обеспечить совместную разработку документа с хранением в git/svn и много другого полезного — могут нажать кнопку ниже, чтобы прочитать немного больше про замечательный редактор Lyx.


    Начнем со знакомства:
    Lyx (ликс) является WYSIWYM редактором (не путать с WYSIWYG). Т.е. основным является не визуальное представление документа на экране, а его содержимое, которое может быть отформатировано так, как надо в конкретном месте.

    Ликс представляет собой бесплатное, с открытым исходным кодом приложение, распространяемое под лицензией GPL v2, кросс-платформенное (Win/Mac/Linux/BSD, в том числе и неоффициальные порты под такую специфику как OS/2 и Haiku).
    Собственно даже Apache OpenOffice и LibreOffice не имеют пакетов для такого разнообразия.


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

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

    Однако, как в том анекдоте "- отличие всего в 7м знаке букве, зато какая разница" — перед тем как начинать редактировать документ, желательно выбрать требуемый класс (формат) документа — от этого зависят две вещи — как можно форматировать документ, и как он будет в конце-концов выглядеть.

    По поводу «форматирования документа» — в отличии от представления Microsoft, которое уже стало классическим, в Ликсе набор стилей параграфов ограничен ровно теми стилями, которые указаны в изначальном классе (шаблоне) документа.
    Например в одном из стандартных классов «article» уровень вложенностей параграфов указывается через цепочку:
    Часть, раздел, подраздел, подподраздел, абзац и подабзац. Параграф при этом может быть нумерованным или без нумерации.

    Собственно такое жесткое разделение, закрепленное за классом документа, выгодно отличает Ликс от стиля WYSIWYG, где можно понаделать стилей в зависимости от погоды в Сингапуре и котировок на молоко в соседних деревнях.

    Класс документа, можно поменять и позднее, но в любом случае придется приложить усилия к тому, чтобы документ стал выглядеть «по новому стилю». Для начала можно использовать стандартный article, и уже спустя некоторое время приходить к тому, чтобы модернизировать стиль, или создавать свои стили. Для последнего, кстати придется потрудиться, поскольку из за отсутствия визуальности, разработка собственного стиля невозможна без глубоких знаний текстового формата Lyx & LaTeX.

    Вот мы и выбрали стиль документа и начинаем писать текст. И вот что странно… Хочется оставить кусочек места для титульной страницы и отступить до следующей. Правда, что все мы когда-то так делали? Однако Ликс не дает вставить лишнего перевода строки.

    Пробуем написать один параграф. За ним следующий. Теперь идем между ними — жмем Enter — вуаля — есть пустое место. Еще один? Не, не дает. Уходим в другую строчку. Но что это? Ликс сам удалил пустой параграф! Печально, где моя Ятрань???
    Та-же самая ситуация и с пробелами.

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

    Конечно не всё так катастрофично — при необходимости можно поставить вертикальный отступ ровно на столько сколько необходимо.

    С остальными полезностями тоже всё в порядке — вставка картинок, автосборка оглавления и индекса. Перекрестные работают даже если сгенерировать PDF (только если генерировать через PDFLATEX и включить HYPERREF в свойствах документа).

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

    Однако текстовый формат хранения документа это огромный плюс тому, кто захочет организовать совместное редактирование документа несколькими людьми с хранением его в системе версионирования вроде GIT/SVN.
    При этом, в сам Lyx встроена поддержка VCS, а также поддержка SVN (через внешние утилиты).

    Отдельное слово хочется сказать про управление содержимым — каждому, кому приходилось реорганизовать документ с переносом целых глав и разделов в другую позицию, приходилось сталкиваться с долгой и нудной операцией выделения нужного куска. А вдруг если что-то случается с нумерацией, то бывает что проще откатить изменения на пару шагов назад, чем поправить.
    В Lyx к операциям переноса глав и изменению отступов подошли совершенно с другого конца — открываем структуру документа, а затем прямо в ней, выбирая нужную часть, раздел или абзац — просто перемещаем их вверх/вниз либо изменяем уровень со всеми вложенными параграфами.

    Возможностей у данного редактора очень много и незачем приводить здесь всю документацию, которую можно прочитать на сайте.

    В качестве резюме:
    Собственно использование Lyx как инструмента для работы с документацией внутри компании и было обусловлено в первую очередь тем, что совместная над документами приводила к тому, что каждый нажимал кнопки как хотел и куда хотел. От этого страдало оформление документов.
    Наличие возможностей хранения в SVN помогло нам как иметь возможность идентифицировать того, кто внес ошибку в документ, так и средствами SVN исправлять эти ошибки, откатывая часть изменений в документе, которые порой были сделаны пол-года назад.
    При этом надо учесть, что начальная часть документа берется из одного места (титульная страница, информация о конфиденциальности и т.п.), другая часть документа редактируется разными людьми, говорящими на разных языках, а третья часть вообще собирается автоматически (документация из исходного кода, конфигурация и состояние серверов и т.п.) и всё это красиво собирается в единый PDF который можно скачать нажав пару кнопок в CustomerCare.

    Надеюсь, что данная статья будет интересна тем, кто ищет схожее решение по хранению и оформлению документации.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Придумаем имена новооткрытым экзопланетам?



    В течение десятилетий названия для небесных тел / космических объектов создавали научные работники. Названия эти, само собой, каталожные, что-то вроде CFBDSIR2149, HD 189733b, 55 Cancri e, и Kepler-69c. Есть названия и посложнее. В общем-то, большую часть новооткрытых космических объектов продолжают именовать ученые, однако, для новооткрытых экзопланет сделали исключение. Для популяризации астрономической науки было решено привлечь обычных людей к созданию «красивых» имен для экзопланет. И сейчас любой из нас может предложить собственное название, правда, нужно следовать некоторым правилам.

    К примеру, предлагаемое имя не должно быть длиннее 16 символов. Это должно быть, в большинстве случаев, одно слово. Кроме того, предлагаемое название должно звучать более-менее одинаково при прочтении носителями разных языков. Само собой, название, данное носителем одного языка, не должно быть оскорблением/глупостью для носителя другого языка.

    Самое важное: нельзя предлагать имена собственные, обычные для домашних питомцев. Нельзя предлагать имена, связанные с ТМ/брендами. Планета Samsung или Apple, конечно, будет очень хорошо рекламировать одноименные компании, но, к счастью, такие имена запрещены.

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

    К слову, для именования двух недавно открытых спутников Плутона тоже привлекли общественность, и были выбраны Kerberos и Styx (Цербер и Стикс). А вот название, победившее в голосовании, Vulcan, было отвергнуто Международным Астрономическим сообществом.

    Если предложений для экзопланет будет много, будет также проводиться голосование. Присылать предложения можно на почту iaupublic@iap.fr (представляю, сколько спама будет сыпаться на этот адрес). Почитать (на английском языке) о «нейминге» планет можно вот в этом документе (.pdf).

    Via IAU

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Научно-познавательные комиксы для детей — выпуск 2

    Прошел уже месяц с первого нашего выпуска детских познавательных комиксов. За это время мы еще подготовили их несколько и хотим ими поделиться с вами.

    Орбита захоронения спутников
    image

    Самый редкий элемент на нашей планете
    image

    Подложить свинью
    image

    Коала и отпечатки пальцев
    image

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

    Так выглядит главная страница boomstarter.ru на момент написания поста.

    image

    Ребята, всем кто нас поддержал (материально, информационно или просто скрестил за нас пальцы на удачу) мы выражаем свою безграничную благодарность! Мы находимся в некотором шоке от происходящего… И всем скептикам, которые говорят что краудфандинг сейчас в России не работает, мы говорим: «а вы не бойтесь, попробуйте тоже!».

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    А что Вы делаете с надоевшими проектами?

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

    image

    Могут быть и какие-то другие причины — пожалуйста оставляйте свои примечания в комментариях.




    Что я делаю с надоевшими/неактуальными проектами?


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 283 человека. Воздержалось 113 человек. Сколько времени у вас обычно занимает над проектами? (какие порядки времени чаще всего встречаются)



    я всегда завершаю свои проекты до конца



    я завершаю только актуальные проекты, остальные даже и не начинаю



    я откладываю проекты на которые у меня нет времени на потом, а когда оно появляется я их довожу до конца



    когда проект мне надоедает или у меня нет на него времени я отдаю его другим разработчикам или сообществу OpenSource



    я легко забываю про скучные и неинтересные проекты и легко их бросаю в пользу новых, более интересных



    я не веду никаких проектов, мне это не интересно и не нужно


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 255 человек. Воздержалось 113 человек. Готовы ли Вы работать над убыточным/имеющим долгосрочную перспективу проектом?



    Бессрочно (могу забросить проект, продолжить только через несколько лет)



    Несколько лет



    Несколько месяцев



    Несколько недель



    Несколько дней



    Несколько часов (проверяю идею на актуальность, если она уже кем-то реализована — даже не начинаю)


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 254 человека. Воздержалось 110 человек. Источник: habrahabr.ru,
    получено с помощью rss-farm.ru




    Да, готов, я потом буду пожимать своих трудов



    Да, готов, но буду работать только над заведомо перспективными проектами



    Да, готов, я вообще работаю над проектами ради собственного удовольствия



    Нет, если проект не принесет мне успеха/денег/власти прямо сейчас я не буду им заниматься

    Наборы эксплойтов для секьюрити ресерчеров

    Вчера я наткнулся на интересный аккаунт в твиттере, который привлек внимание странными твитами, адресованными ресерчерам. Внимание привлекли следующие свойства:
    • Твиты были адресованы секьюрити ресерчерам (Микко Хиппонен, tachion24, Charlie aka Kafeine, Брайану Кребсу и Security Obscurity aka SecObscurity), которые занимаются, в т. ч. исследованиями наборов эксплойтов (exploit kits) и пишут о них.
    • Название аккаунта «paunch big hecker» недвусмысленно намекает на известного человека под ником Paunch, автора Blackhole exploit kit.
    • Содержание твитов намекает на то, что это на страницы статистики наборов эксплойтов (Nuclear Pack, Cool Exploit Kit), причем указываются сами названия наборов.
    Такое своеобразное название аккаунта очевидно было выбрано для того, чтобы привлечь больше внимания.



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





    Kafeine полагает, что в этом случае речь идет не об атаках на ресерчеров, а скорее о предумышленной утечке статистики работы панелей.

    Пост Брайана http://krebsonsecurity.com/2013/08/personalized-exploit-kit-targets-researchers/.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Проекту Debian 20 лет!

    16 августа 1993 года был анонсирован выход дистрибутива под названием (от имени основателя дистрибутива Ian Murdock и его жены Debra).


    Debian считается одним из старейших и стабильных дистрибутивов. Дистрибутив придерживается философии стабильности и открытости и имеет наибольшее хранилище пакетов.
    Последняя, на данный момент, версия Wheezy поддерживается 13ю! архитектурами. На основе Debian выпущено более 138 дистрибутивов.
    Наглядное изображение (кликабельно)
    Празднование дня рождения Debian проходит в Швейцарии на конференции DebConf13.

    Debian является одним из самых популярных серверных дистрибутивов, даже NASA использует систему на рабочих местах космонавтов МКС и использовался в экспериментах на шаттле Колумбия в далеком 1997.

    На данный момент выпущено 13 релизов Debian, дата 14го выпуска еще не определена, но известно, что он будет называться «jessie».

    Стабильные и тестируемая версии операционной системы Debian называются именами персонажей мультфильма «История игрушек»
    Нестабильная версия дистрибутива Debian постоянно носит кодовое имя Сид (sid), по имени отрицательного персонажа из мультфильма, который ломал игрушки.

    Пожелаем сообществу развиваться дальше и радовать нас своими релизами!

    Официальный сайт Debian: CL_Prefix_debian.org

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Киберприглашение на свадьбу или о том, как эффектно разрушить шаблоны

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


    Итак, идея
    Всё началось с того, что в один прекрасный день я решил жениться! Заявление, подготовка к празднику, все дела. Но вот задача: сделать оригинальные приглашения на свадьбу. Подписывать куски картона не хотелось. Душа просила хардкорного хэндмэйда, далёкого от традиционных свадебных шаблонов. И вот на моё “и вообще, можно электронные девайсы сделать” невеста сказала: “Круто! Давай!”


    К тому моменту мой опыт сводился к спаиванию Фридуины из набора деталек и ритуальному миганию светодиодом. Я с ужасом прикинул, что руками предстоит собрать не один и не два, а 33 экземпляра, заранее попрощался с предстоящими летом — и понеслась…

    Февраль. Свадьба в августе, но мне уже казалось, что я ничего не успею. Потому что, чёрт его знает, где и что пойдёт не так. Однако, постепенно стал вырисовываться план: слепить в один кусок LCD-экранчик, батарейку, кнопку и какой-нибудь контроллер, чтобы по нажатию кнопки устройство показывало на экране сообщение по строкам.

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

    Экран
    Подобрал в каталоге ближайшего магазинчика радиодеталей, взял сначала один на пробу. По характеристикам вышло следующее: LCD, текстовый, русские буквы, 1 строка в 16 символов, без подсветки. Называется WH1601A-NGG-CT (datasheet), стоит сто с лишним рублей. Оказался волне удачный экранчик, позже закупил их целую коробку:


    Контроллер
    Контроллер подобрал из каталога Atmel (на сайте Atmel давите MCU Selector). Atmel, потому что с ардуиной у меня уже был маленький опыт, а на easyelectronics есть отличный курс про AVR-контроллеры. Искал такой,
    • чтобы ног хватало, но было как можно меньше
    • чтобы DIP-корпус (SMD я ещё не паял и не хотел рисковать),
    • чтобы энергопотребление могло быть маленьким
    • и чтобы в ближайшем магазине было в наличии.

    Вышло ATTiny 2313A-PU (Даташит).

    Батарейка
    Экранчику нужно было питание 5В, поэтому после недолгих исследований решил использовать пару батареек CR2016, сложенных стопочкой в держателе для CR2032.

    Всякое другое
    Как ни странно выяснилось, что мелочевку (резисторы, конденсаторы и пр.) оптимальнее покупать не в СПб, а заказывать из под Йошкар-Олы (магазинчик ekits.ru). Нашлось всё и по нормальным ценам.

    Прототип
    Освоил экранчик: припаял к нему провода, поэкспериментировал из Ардуины, добился, чтобы он писал буковки по очереди с заданными паузами. Библиотеками не пользовался, хотел всё сам. Вот такой код получился.

    Все было готово к работе над прототипом.

    Март-апрель. Долгий период написания прошивки на ассемблере (намеренно не на С, чтобы лучше прочувствовать архитектуру), рисования и разводки схемы. Показал невесте. “А давай”, — говорит она мне — “оно еще и лампочками мигать будет”. Пришлось в процессе встроить “еще и лампочки”: добавил две пары светодиодов и работу с прерываниями, разводка немного усложнилась. (Светодиоды заказывал все так же, из Йошкар-Олы). Схема в результате вышла такая:


    Для начинающих, как я, пояснения к схеме:
    Пояснения к схемеПосередине контроллер, справа экранчик. Семь проводов от контроллера к экранчику это три управляющих и четырёхбитная шина данных. Всё по даташиту. Питается экранчик не напрямую, а с ножки PD2 (контакт V-LCD), это оттого, что большую часть времени девайс не работает, контроллер уходит в sleep, и на питание экранчика батарейку тоже не тратит. Ещё там есть VO-LCD, который подаётся на контакт VO экранчика. Согласно даташиту туда надо подавать некоторое напряжение больше нуля, но меньше VCC, этим напряжением регулируется контраст экранчика. Даташит предлагает пихать туда реостат и регулировать на ходу. Но не в каждую же плату реостат пихать! Так что подобрал напряжение экспериментально и соорудил делитель напряжения, чтоб его получить. Это вот конструкция из двух резисторов внизу. Ещё внизу нарисовано, что питание изначально берётся с батарейки и что в питание вставлен конденсатор для защиты, например, от дребезга при вставлении свежих батареек. Ну, собственно и всё. Ещё там есть кнопка ресета и четыре светодиода, включённые попарно.

    А вот такая прошивка.

    Разводка для первого раза вышла непростая, так что вполне вероятно, что я нарушил какие-то каноны. Пришлось уживаться с кучей условий:
    • Плата по размерам должна была быть чуть больше экранчика, чтобы удобно было жать на кнопку старта.
    • Коннектор и крепёжные дырки — соответствовать коннектору и дыркам на плате экранчика. (Дырки я потом соединил винтами).
    • Светодиоды (по дизайнерской задумке) — непременно смотреть в разные стороны.


    В результате обошёлся двумя перемычками, на схеме они синие:


    Собрал всё на макетке, долго отлаживал, добился чтоб работало… Да, прошивал Ардуиной по схеме, разжёванной тут.Схема требует соединить ресет с питанием через резистор: я резистор подвесил прямо в провод.

    И да, важно было, чтобы в каждом девайсе был персонализированный текст (приглашение же!). Текст хранился в прошивке в виде дампа (“.db 0xa2, 0xa3...”). Причём таблица кодировки у экранчика своя и с особенностями. Она, например, экономит и содержит только те буквы кириллицы, для которых нет аналога на латинице. Для удобной перекодировки сделал утилитку на java.

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

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

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

    Производство
    Шёл май. Я начал делать первый экземпляр. Расписывать ЛУТ и травление не буду, мануалы DiHALT`а все читали. Расскажу только об отдельных особенностях и отличиях от мануала.
    • Травил в смеси медного купороса и поваренной соли. Это менее едко и ингредиенты лежат в ближайшем строительном супермаркете.
    • Сверлил сверлом в 1мм по металлу (меньше в том супермаркете не было) и дрелью, настоящей, полноразмерной. Рука оказалась достаточно тверда, чтобы не поломать сверло и не смазать отверстие. А шуруповёрт оказался, хоть и легче, но слишком медленный. Кстати, совершенно верна рекомендация о том, что надо беречься пыли! Она очень мелкая, белая и почти не видна, если не ссыпать кучкой. Но если окажется в воздухе, горло дерёт страшно.
    • Сначала лудил, а потом сверлил, хотя все везде рекомендуют наоборот. Но так же проще! Ободок отверстия становится толще и в начале сверления дополнительно поправляет прицел.
    • Делал партиями — так быстрее. То есть, десяток плат проходят первую стадию, потом вторую и т.д. Получается меньше переключений контекста, меньше перекладываний инструмента и, соответственно, быстрее . Стадии такие:
      1. Отрезать кусок платы и пошкурить
      2. Пригладить бумажку с рисунком и отмыть её

      3. Протравить плату
      4. Залудить дорожки
      5. Насверлить отверстий
      6. Припаять всё кроме контроллера
      7. Вставить контроллер в макетку и прошить
      8. Впаять контроллер
      9. Соединить с экранчиком винтами

    Получилось вот так. На видео, правда, пока без винтов.

    Вот и всё. Устройства были готовы.


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

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

    А инструкция, которая видна на фотографии, вот так


    В общем, эффект достигнут! Гости в восторге, свадьба удалась, у нас — по плюс-много к опыту и желание продолжать эксперименты…

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Хорошая локализация: миссия невыполнима

    Добрый день, читатель! Мы – компанияAll Correct localization, занимаемся локализацией ПО с 2006 г., а игр – с 2008 г., и за это время успели попасть в двадцатку крупнейших переводческих компаний Восточной Европы. На страницах нашего блога мы будем делиться с вами опытом нашей работы. Думаем, он окажется полезным многим амбициозным разработчикам программного обеспечения и игр.
    image

    Хотите узнать рецепт отвратительной локализации? Чтобы прямо ни в какие ворота? Без малейшей надежды на успех? Тогда слушайте!

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

    Естественно, вся редакторская группа пришла в восторг! По-настоящему креативные задания попадаются нам нечасто. Переводчица постаралась на славу. Вспомнила все: и булгаковское «Сижу, починяю примус», и «Свежее дыхание облегчает понимание», и даже бозон Хиггса.

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

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

    Но когда мы открыли сами тексты, то поняли, что это были еще цветочки! И вот, внимание, обещанный рецепт отвратительной локализации.
    1. Поручите корейцам написать список возможных вопросов чат-боту.
    2. Поручите корейцам перевести его на английский.
    3. Этим же корейцам (!!!) поручите перевести его на русский.
    4. И наконец, поручите им же придумать ответы на английском, соответствующие, на их взгляд, нынешним реалиям России.
    5. Всю эту кашу из английского и русского отправьте русским вместе с формой, в которую они должны записывать каждый чих и согласовывать с заказчиком. Разумеется, заносить все нужно на английском.
    Вы считаете, что вопрос переведен некорректно? Заносите в форму!

    Вы считаете, что предложенный ответ не соответствует вопросу? Заносите в форму!

    Вопрос есть, а ответа на него нет? Или есть ответ, но на что — неясно? Ну, в общем, вы уже поняли…

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

    Вот некоторые примеры творчества корейцев:







    Оригинал «Перевод» You're still here, right?А ты пойдешь? How about if we fuck?Прикалываешься надо мной? I beg your forgiveness.Чо? I understand, don’t worry about it.Спокойно, Маша, я Дубровский! Areyouafairy?Ты относишься к гомосексуалистам?
    Примечательно, что на последний вопрос ответ предполагался: I'm not a mythical creature (Я не мифическое существо). Знайте, гомосексуализм — это миф!

    image
    Остальные иллюстрации к феям и гомо… лицам нетрадиционной ориентации были безжалостно отвергнуты цензурой

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

    Лишь иногда удавалось более-менее удачно пошутить в рамках предложенного ответа.


    ХХХ is an efficient email system.ХХХ — эффективная почтовая система. I've heard it really delivers.Говорят, она реально доставляет.
    Отдельного внимания заслуживает сама подборка вопросов. Почему-то довольно немалую часть в ней занимают темы сексуальной ориентации и секса вообще. Причем секса с самим эм-м-м… устройством, т. е. чат-ботом.

    Ты традиционной сексуальной ориентации? Как ты занимаешься сексом? Ты занимаешься киберсексом? Хочешь заняться сексом со мной? Ты любишь ласкать себя? Ну и дальше в том же духе.

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

    image
    А вот у Кутраппали с Сири все было чисто и невинно…

    Целый ряд вопросов был также посвящен таким острым темам, как взаимоотношения между народами. Например, в оригинале, т.е. в корейской версии чат-бота, речь шла об отношениях Кореи и Японии.Для тех, кто не знает: отголоски японской колонизации все еще отдаются болью в душе многих корейцев. Соответственно, в русском варианте корейцы решили заменить в своих вопросах Южную Корею на Россию, а Японию на Германию. В итоге получилось следующее:

    I think that the Japanese government should formally apologize to comfort women.

    Германия должна извиниться перед русскими женщинами.

    I think that there needs to be a formal apology from Japan to Korea.

    Немцы еще не искупили свою вину перед русскими.

    и др.

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

    Что примечательно, часть вопросов о культуре так и остались нелокализованными, т.е. в них все еще фигурируют японцы:



    I'm not sure about Japanese politicians.Политики Японии какие-то чудики. I prefer not to play Japanese games.Японские игры говно.
    (отличный перевод последней фразы, не так ли?)

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

    Итак, что же я хочу всем этим сказать? А вот что:

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

    Все это очень кратко можно проиллюстрировать вот таким комиксом:

    image

    Автор записи Epoha3004

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Из песочницы] Общая психология: usability

    То есть как — психология?
    Некоторые наши специализированные компании, предоставляющие услуги на рынке юзабилити, уже много лет укомплектованы дипломированными психологами (чаще всего, выпускниками кафедр инженерной или общей психологии). Действительно, уже более полувека русскоязычная психология исследует процесс взаимодействия человека и техники (первая наша книга по теме) и, в частности, интерфейсы между оператором и техническим устройством. Конечно, терминология эта носит сугубо эргономический характер, однако это не затрудняет перенос знаний в IT-среду (например, Дмитрий Сатин, основатель UsabilityLab, является выпускником самой эргономической кафедры факультета психологии МГУ).
    Психологическое знание в России популяризируется слабо, хотя само по себе может быть очень полезным для разработки программных продуктов. Я попытаюсь коротко изложить некоторые базовые принципы проектирования — как их видно изнутри классических психологических (преимущественно, когнитивных) работ. Я уверен, что буфер, которым является юзабилити, IT-индустрии не нужен: психологические знания можно научиться применять напрямую.


    Корень юзабилити
    Человеческие возможности обработки информации ограничены. Рабочая память, «область ясного сознания» не может вместить больше 5-9 элементов, если заниматься только припоминанием, и больше 3-5 – если параллельно заниматься чем-то ещё, например, конструировать модель системы, формулировать мысль, каждую секунду отнимать от сотни по три в уме и так далее. Причём пропускная способность человека как системы переработки информации динамична и напрямую зависит от структуры данных, с которыми человек взаимодействует. То есть одна и та же задача может оказаться для абстрактного пользователя как лёгкой, так и сложной — в зависимости от того, как она представлена интерфейсом. Задачи, которые решает пользователь с помощью программного продукта, обладают внутренней сложностью, и для их решения необходимо некоторое умственное усилие. Избежать внутренней сложности невозможно. Главная задача интерфейса — свести к минимуму сложность внешнюю, единственным источником которой он сам и является.



    Цель юзабилити-проектирования
    Основная цель гуманного проектирования – это забота о пользователе. Back-end-разработчик обеспечит потребителя необходимыми средствами решения его задач, в ответ на это дизайнер и юзабилити-инженер должны сделать средства доступными, а взаимодействие с программой – предсказуемым. С помощью этих средств хороший продукт контролирует эмоциональное состояние пользователя.
    Общепсихологическое знание, которое поможет нам в этом, можно упаковать в несколько базовых принципов.

    Принцип минимизации усилий
    Основными показателями удобства интерфейса являются сложность выполнения необходимых пользователю задач и время, затрачиваемое на каждую из них. Именно эти показатели определяют объём усилий, которые, по ощущению пользователя, расходуются на выполнение действия. Показатели имеют разные приоритеты в зависимости от обслуживаемой интерфейсом деятельности.
    Сложность. Любое действие имеет свою, внутреннюю, сложность, от которой невозможно избавиться, не сделав это действие бессмысленным. Например, если Вы хотите совершить покупку, Вам не избежать финансовых операций, как и принятия решения по поводу этих операций. Эти два действия обеспечат внутреннюю сложность Вашей деятельности. Вы примете решение, вероятнее всего, без внешних посредников. Однако на этапе произведения финансовых расчётов Вы будете применять различные средства, созданные внутри сообщества. Пусть это будут бумажные деньги. В этом случае процедура финансовых расчётов будет разложена на последовательность движений, простой арифметики и познавательных действий (позволяющих Вам отличать купюры и монеты друг от друга), поддержанную петлёй обратной связи, которая корректирует движения на основе опознания и арифметики. Все эти действия предъявляют к Вам требования и являются внешней сложностью задачи, созданной несовершенством интерфейса «деньги-покупатель».
    Таким образом, внешняя сложность задачи всегда является разницей между актуальной сложностью задачи и минимальной возможной сложностью задачи. Минимальная сложность умственной задачи достигается в утопическом случае: любое действие осуществляется в один психологический квант, «одну мысль», без необходимости внешних действий и, тем более, коррекций. «Мысль» как единица измерения никуда не годится, но пафос прост: минимизируем количество действий, а особенно – действий, требовательных к характеристикам их исполнения. Так, попасть курсором в кнопку 10*10 требует гораздо более точных сенсомоторных координаций, чем в кнопку 100*100 – значит, требует большего усилия (пресловутый закон Фиттса учитывает время, но не усилия, и игнорирует контекст. Однако лучше, чем ничего). Оценка сложности каждого поведенческого действия опирается на психофизиологические и – широко – эргономические знания; оценка действий умственных гораздо сложнее и пока, в основном, происходит на базе экспериментальных данных о разнообразных ограничениях человека как системы переработки информации и результатов популяционных исследований.
    Основной способ снизить нагрузку на пользователя – организовать информацию так, чтобы в фокусе внимания располагались 1-5 элементов, которые:
    1. Имеют одинаковую или схожие функции;
    2. При взаимодействии с ними приводят к схожим результатам;
    3. Сообщают своими сенсорными свойствами о всех действиях, которые можно с ними совершить (принцип экономичной ментальной модели – ниже);
    4. Для взаимодействия с ними не требуют помнить ничего, кроме собственного намерения.
    Лучшее средство, как известно, незаметно. Работая с хорошим интерфейсом, Вы замечаете его, только если отвлекаетесь от решаемых задач. Когда же Вы работаете, есть только цель и Ваши действия по её достижению.

    Временные затраты были более или менее удачно формализованы в GOMS-моделировании, (полноценно этот метод применим только к строго регламентированным деятельностям), которое частично можно использовать при разработке любых приложений. В целом, при разработке интерфейса не так важно, сколько именно времени в среднем тратит пользователь на выполнение какого-либо действия, главное – грамотно составить последовательности из этих действий, отвечающие основным запросам (сценарии важнее действий). Временные и умственные затраты часто находятся в противостоянии. Например, организуя многоуровневый список, часто приходится выбирать между его шириной и глубиной: глубокий список снизит умственные затраты на ориентацию в каждом уровне, но замедлит пользователя на пути к нужному ему элементу; в то время как широкий список ускорит выбор элемента, но значительно повысит нагрузку из-за увеличения количества одновременных альтернатив.

    Принцип экономичной ментальной модели
    Пользователи моделируют приложение. Каким бы простым ни был Ваш сервис, у каждого потребителя будет уникальная модель, исходя из которой он будет проектировать последовательности действий для достижения своих целей. По сути, ментальная модель является метафорой происходящего между человеком и приложением, позволяющей быстро ориентироваться в законах, по которым приложение устроено, и правилах взаимодействия с ним. Эта метафора появляется всё по той же причине: возможности человека обрабатывать информацию ограничены, и все правила в «сыром» виде просто невозможно запомнить: они автоматически объединяются в экономичную (насколько это возможно) структуру. Многие разработчики сбрасывают задачу создания и поддержания ментальной модели приложения на пользователей, устраивая анархию и провоцируя ошибки. Качество ментальной модели легко оценить по объёму инструкции, необходимой для полноценной работы или, если всё не так плохо, по времени врабатывания в приложение (времени, необходимого для освоения всех функций программы, отвечающих запросам данного пользователя, и осознания степени соответствия спроса на функции в продукте его предложению). Ментальная модель придаёт поведению интерфейса предсказуемость. Если средний пользователь после первичного ознакомления с Вашим продуктом может правильно ответить на десять случайных интерфейсных вопросов из десяти, Вы создали удачную ментальную модель. (Вопросы при этом должны касаться поведения интерфейса, например: «Что произойдёт, если нажать эту кнопку?» — или: «Что нужно сделать, чтобы…?»)

    Экономичная ментальная модель:
    1. Организована просто и иерархично: использует как можно меньшее количество объектов и правил, не содержит исключений, использует знания из повседневной жизни (например, аналогии элементов интерфейса реальным вещам: элемент, который выглядит, как тумблер, не может иметь активными оба состояния одновременно; зона, реагирующая на наведение курсора, не может быть больше зоны, реагирующей на клик – иначе возникают противоречия);
    2. Вынесена вовне: если Ваш продукт устроен (с точки зрения пользователя!) слоями, визуализируйте эти слои. Если это среда с событиями – обеспечьте фон и хорошую различимость событий на нём;
    3. Однозначна: если элемент сообщает о себе что-то, то он сообщает только это и ничего другого или противоречивого (!);
    4. Внутренне связна: дополнительные связи между структурными единицами приложения снижают итоговую сложность ментальной модели, отображение одной и той же связи несколькими способами позволяет пользователям с разными стилями деятельности одинаково эффективно работать с продуктом.

    Только разрабатывая продукт, можно понимать его истинную структуру, поэтому разработчики ответственны за ментальную модель системы, передаваемую в интерфейсе. Модель не может сложиться сразу, но она ядро интерфейса, и уделить ей недостаточно внимания – неизбежно снизить понятность программы и удобство пользования.
    Ментальная модель существует на нескольких уровнях. Требования к ним наследуются снизу вверх: необходимое свойство кнопки является необходимым свойством всего приложения и всех промежуточных уровней. Выделим четыре основных уровня:
    1. Элемент (кнопка, ссылка, скролл-бар, текстовое поле…), атом юзабилити. На этом уровне ментальная модель должна показывать пользователю три свойства:
      • является ли элемент интерактивным;
      • какие взаимодействия с элементом возможны;
      • к чему приведёт каждое из этих взаимодействий.
    2. Блок (навигационная панель, список, текстовое поле с принадлежащими ему кнопками и подсказками…). Блок состоит из элементов, и дополнительным требованием ментальной модели к нему является цельность: блоки отграничены друг от друга пространственно и с помощью обратной связи, взаимодействие между ними минимизировано. Количество элементов в блоке, как правило, соответствует среднему объёму внимания человека, поэтому именно блок является основной единицей взаимодействия «пользователь-приложение», и понимание этого предоставляет нам множество возможностей разгрузить пользователя.
    3. Страница состоит из блоков. Дополнительных требований к странице (относительно первых двух уровней) два. Первое из них – указание на положение в структуре сайта/приложения. Страница чаще всего моделируется как пространство, экран, разворот книги и так далее: система блоков, встроенная в пространство всего приложения, имеющая свой уникальный адрес (в понимании пользователя! Не путь в сайте, а некое место, в которое можно пройти с помощью определённой последовательности внутренних ссылок и из которого можно этим же образом выйти. Узел в сети приложения). Положение страницы в сети приложения, количество «входов» и «выходов» определяют её оформление. Второе требование к странице – функциональное единство. Каждая страница создана для какой-то определённой цели, и эта цель отражается в атрибутике (стиле) страницы, выборке блоков и их взаимном расположении.
    4. Приложение состоит из страниц. Ментальная модель приложения – это его глобальная функция (что делает этот сайт?) и структура (как он организован? Из чего состоит? Как с ним работать?). Дополнительное требование к ментальной модели сайта: прозрачность его внутреннего устройства, сети переходов между страницами.

    Как создать ментальную модель?

    Каким образом передать пользователю всю эту информацию? Использовать для этого текст означает, на самом деле, писать инструкцию, то есть капитулировать перед задачей построения ментальной модели и сбрасывать эту задачу на пользователя = делать приложение непонятным. Передать модель текстом, научить пользователя, в принципе, возможно, однако требует большой подготовки за пределами юзабилити: естественные языки имеют низкую выразительную мощность, когда дело доходит до моделей. Поэтому передавать пользователю ментальную модель системы гораздо проще образами, скрытыми правилами и аналогиями.

    Скрытые правила – законы организации приложения любого уровня, выраженные невербально. Часто они носят внешний относительно приложения характер, то есть наследуются из более широкого контекста. Прямоугольник высотой чуть больше строки с высветленным текстом, обращающимся к пользователю («Чем Вы заняты?», «Что нового?», «Введите описание задачи…»), считается полем ввода текста. Его функция никак не следует из формы или других характеристик, однако с развитием Интернет-технологий значение закрепилось в культуре, и теперь сделать, например, кнопку с таким внешним видом означает запутать подавляющее большинство пользователей. Это скрытое правило базируется на аналогии.
    Аналогии – перенос некоторых свойств объекта на другой объект, используя совпадающие характеристики образов восприятия этих объектов или способов взаимодействия с ними. Поле текстового ввода на разнообразных стенах в соцсетях аналогично уже написанным сообщениям по пространственным характеристикам (размер и положение), а также аналогично полям ввода и вывода некоторых технических устройств (строке калькулятора и счётных приборов в автомобиле, телеграфной ленте, рукописной строке в тексте). Наиболее выгодные аналогии – со знакомыми пользователю в реальной жизни предметами. Типичные примеры – это инструмент «вырезать» (уничтожает содержание в одном месте, предоставляя возможность восстановить его в другом), предметные иконки (приоткрытая дверь – выход, шестерёнка – механическое устройство, настройки; динамик с волнами около него – звук), постраничный вид документа в текстовых редакторах, файловые системы всех популярных операционных систем (и само слово «файл»). Найти продукт с графическим интерфейсом, не использующий аналогии, практически невозможно. Именно аналогии Д.Норман положил в основу принципа естественного соответствия, подчёркивая этим названием необходимую интуитивность аналогий, их понятность без размышлений.

    Принцип безошибочности
    Все пользователи совершают ошибки. Как и в случае сложности, задача идеального юзабилити-инженера – избавить пользователя от ошибок по вине программы и позволить ему исправить ошибки, допущенные по его собственной вине. В первом приближении что-то может идти не так на двух уровнях: моторном и смысловом. Типичные ошибки моторного уровня – неточное позиционирование курсора при клике, промах по клавише, неверное опознание буквы. Ошибки смыслового уровня – это неверное опознание слова, совершение ненамеренного действия, забывание намерения… В большинстве случаев уровень ошибки не имеет особого значения, однако есть ситуации, в которых защита именно от определённого типа ошибок в корне изменяет диалог человека с программой.
    Возможные ошибки пользователя зачастую невозможно моделировать без учёта его состояния, а этот фактор определяет многое во взаимодействии потребителя с продуктом. Утомлённый, задумавшийся или взволнованный (тонизированный) пользователь вероятнее допускает ошибки обоих уровней, невозможные для пользователя в оптимальном рабочем состоянии.
    Защита от моторных ошибок — ограничения на минимальный размер шрифта и кнопки, на минимальное расстояние между границами соседних кнопок.
    Защита от смысловых ошибок — максимальная различимость функциональных элементов, их разумная группировка (экономизация ментальной модели) и самое главное – очевидные защиты от деструктивных действий, особенно если такие действия необратимы. Возможные способы защиты от фатальных ошибок:
    • труднодоступность деструктивных действий (структура диалога),
    • запрос подтверждения (детализированный, указывающий на объект воздействия!)
    • возможность отменить совершённое деструктивное действие (защищает не только от ошибок, но и от импульсивного поведения).

    Как снизить нагрузку?

    Понятие нагрузки, или когнитивной нагрузки, сложно формализовать, однако в лабораторных условиях уже много лет проводятся исследования, моделирующие взаимодействие человека с различными системами. Эти исследования показывают несколько базовых факторов ментальной нагрузки, на основе которых можно получить простые правила снижения нагрузки, то есть уменьшения внешней сложности действия:
    1. Напоминания и внешняя память: чем меньше нужно помнить пользователю, тем лучше. Даже собственное намерение он может забыть, если на пути к его реализации встанут несколько перегруженных экранов или хотя бы одно непредсказуемое событие;
    2. Непрерывность деятельности и защита от прерываний: давайте пользователю возможность закончить начатое, прежде чем отвлекать его. После каждого отвлечения ему понадобится время, чтобы вспомнить, чем он занимался, и вработаться в прерванную деятельность – и ответственность за это потраченное впустую время лежит на разработчике. Но пока софт мало знает о пользователе. Полноценные сенсоры ещё не стали непременным атрибутом рабочего места, но они смогут значительно облегчить нам жизнь.

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    А квайн ли это?


    Пользуясь тем, что на Хабре проходит очередной месячник квайнов (см., например, Теорема Клини о неподвижной точке: квайны или Мультиязыковые квайны), рискну рассказать и одну свою историю. В ней не будет таких сложностей и заумствований, как в упомянутых топиках, поэтому данный текст можно воспринимать как пятничное развлечение.

    Дело происходило почти четверть века назад, в эпоху отсутствия всеобщей компьютеризации и интернета. Возник у меня как-то вопрос — а можно ли написать программу, выводящую свой собственный текст. Слова «квайн» в те времена никто из моих знакомых не знал, а посмотреть в википедии я не мог «за отсутствием таковой» ©.
    Промучался я над этой задачкой неделю, но таки победил её. Программа получилась корявенькая, длинная, но требованию удовлетворяла. Ужасно гордый собой, я начал предлагать эту задачу всем своим друзьям. По ходу дела пришлось уточнять условия — нельзя читать из файла, программа должна быть не пустой. Обычно после этого товарищи надолго задумывались.
    Однако, один из друзей мне моментально ответил, что это, дескать, элементарно, и тут же предоставил мне требуемую программу, удовлетворяющую поставленным условиям.
    Оказалось, что я всё-таки упустил одно важное и, казалось-бы, очевидное условие. Однако без его явного упоминания задачка действительно становится тривиальной. Тем не менее даже в современной статье о квайнах в википедии это условие почему-то отсутствует. Хотите знать, что это за условие?


    Программа была примерно такая:
    <code class="delphi">program quine;
    var i:byte;
    begin
    randomize;
    for i:=1 to 91 do write(chr(random(255)));
    end.
    </code>
    Здесь язык — Паскаль, но, надеюсь, идея понятна: отсутствовало условие о том, что программа должна выводить собственный текст при каждом запуске.
    Приведённая программа каждый раз выводит случайную последовательность из 91 символа. Вероятность того, что при этом получится текст исходной программы, крайне мала. Однако эта вероятность ненулевая!

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

    Конечно, приведённая здесь программа отсылает нас к теореме «о бесконечных обезьянах», которая утверждает, что абстрактная обезьяна, ударяя случайным образом по клавишам печатной машинки в течение неограниченно долгого времени, рано или поздно напечатает любой наперёд заданный текст (в частности, «Гамлет» Шекспира).
    Кроме различных сомнений философского характера в истинности этой теоремы, о большинстве которых можно прочитать из указанной статьи в википедии, есть и практические сложности с имплементацией данного квайна. Даже если мы позволим компьютеру работать неограниченное количество времени, возможно, что текст программы так и не будет ни разу напечатан. Дело в том, что операторы randomize и random обеспечивают выдачу псевдо-случайных чисел, а отнюдь не генерируют настоящую случайную последовательность. Поэтому может так статься, что именно нужная нам последовательность символов не появится никогда в силу этой псевдо-случайности.
    Тем не менее оригинальность такого подхода к задаче заслуживает внимания!

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    СПО как средство кооперации авторов идей предметной области и производителей софта

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

    Идея замещения исполнителей заданий при помощи специальных правил
    Системы автоматизации процессного управления раздают задания исполнителям в соответствии со схемами бизнес-процессов, а также контролируют их выполнение.
    Замещение исполнителей заданий используется в случаях, когда пользователь, которому предназначено задание, не имеет возможности его выполнить, — например, заболел, находится в отпуске или командировке. — Система перенаправляет задание другому пользователю.
    Традиционно эту проблему решают при помощи импорта организационной структуры предприятия в систему процессного управления и использования функций замещения, основанных на положении сотрудников в административной системе управления. В некоторых системах эту проблему решают при помощи вставки программного кода, реализующего перенаправление заданий, непосредственно в бизнес-процессы.
    Оба этих решения неудобны: Организационная структура предприятия является отдельной сущностью и дублировать ее в системе процессного управления нежелательно, она также используется в других системах предприятия (ERP, CRM и т.п.). В случае использования программного кода бизнес-процесс становится неудобным для модификации, для изменения замещения часто требуется привлекать программиста.
    Но главное — эти решения неудобны управленцам, потому, что они не соответствует их мышлению. В случае замещений исполнителей задач управленцам гораздо комфортнее думать «в терминах» людей, а не бизнес-процессов. Им удобнее не перебирать все бизнес-процессы, в которых теоретически может участвовать замещаемый сотрудник предприятия, а явно задать замещение для конкретного работника, может быть, указав при этом какие-то условия, при выполнении которых замещение будет выполнено.

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

    Реализация идеи
    Идея была реализован в российском проекте разработки свободной системы управления бизнес-процессами и административными регламентами RunaWFE следующим образом:
    В свойствах пользователя была добавлена возможность задавать набор правил замещения. Для конкретного пользователя правило замещения состоит из двух частей:
    • Заместитель (Функция над организационной структурой предприятия, возвращающая пользователя-заместителя)
    • Условие применения (Критерий)
    На рис. 1 приведена форма задания правил замещения в свойствах пользователя

    Рис. 1. Форма задания правил замещения

    Для активации механизма замещения в свойствах пользователя был добавлен статус, который может принимать одно из двух значений:
    • Активен
    • Не активен
    Механизм замещения применяется только к пользователям, имеющим статус «не активен».

    Алгоритм обработки правил замещения
    При формировании списка заданий исполнителя правила замещения, относящиеся к данному исполнителю, просматриваются сверху вниз до тех пор, пока либо не будет найдено первое по порядку подходящее правило замещения, в котором выполняется условие в «критерии» и заместитель имеет статус «Активен», либо будет выяснено, что ни одного подходящего правила нет.
    В список заданий этого заместителя, если он будет найден, будет перенаправлено данное задание. На рис. 2 в качестве примера показан список задания пользователя Бабочкин, в который по правилу замещения перенаправлено задание пользователя Гусеницын.

    Рис. 2. Перенаправленное задание в списке заданий пользователя

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Из песочницы] Набор регулярных выражений для MarkDown

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

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

    H1
    <code class="perl">^# (.)+$ // стандартный заголовок
    ^.+$\n^={3,}$ // заголовок с двойным подчеркиванием
    </code>
    H2
    <code class="objectivec">^#{2,2} (.)+$ // стандартный заголовок
    ^.+$\n^-{3,}$ // заголовок с одинарным подчеркиванием
    </code>
    H3… H6
    <code class="objectivec">^#{3,3} (.)+$  ... ^#{6,6} (.)+$
    </code>
    bold ( **Текст** )
    <code class="objectivec">(?<!\*|\\\*)\*{2,2}[^\*\n].+?[^\*]\*{2,2}(?!\*|\\)
    </code>
    italic ( *Текст* или _текст_ )
    <code class="objectivec">((?<!\*|\\)\*[^\*\n].+?[^\*|\\]\*(?!\*))|(_.+?_)
    </code>
    bold italic ( ***Текст*** )
    <code class="objectivec">(?<!\*|\\)\*{3,3}[^\*\n].+?[^\*|\\]\*{3,3}(?!\*)
    </code>
    monospace ( `текст` )
    <code class="objectivec">`[^`]*`
    </code>
    Numbered list
    <code class="objectivec">(^\d{1,3}\. .*$)+|(^ {1,10}\d{1,3}\. .*$)+
    </code>
    Unnumbered list
    <code class="objectivec">(^(\*|\+|-) .*$)+
    </code>
    image ![img alt](http://image.url/img.png)
    <code class="objectivec">!\[[^\[\]]*?\]\(.*?\)
    </code>
    url [ссылка](http://site.com/)
    <code class="objectivec">\[[^\[\]]*?\]\(.*?\)|^\[*?\]\(.*?\)
    </code>
    block quotes
    <code class="objectivec">^>{1,4} (.)+$
    </code>

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

    image

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Дайджест новостей из мира мобильных платежей #3

    Тем временем, пока Facebook тестирует собственную систему платежей, предлагаем ознакомиться с последними новостями из мира мобильных финансов. Читайте самые яркие новости прошедшей недели под катом.




    Мексиканский торговец в сфере электронной коммерции LINIO представил мобильное торговое приложение

    Мексиканский интернет-магазин LINIO запустил свое мобильное приложение для владельцев устройств на базе Android. Функционал приложения позволяет искать, просматривать и покупать товары, получать уведомления о новых интересующих позициях и заключать сделки. Покупки оплачиваются с помощью банковских карт.
    Пока приложение доступно для жителей Мексики, но в ближайшем будущем планируется запуск в Колумбии, Перу и Венесуэле. Кажется, теперь понятно, почему приложение вышло только на Android.

    SAP купила разработчика технологий для электронной коммерции Hybris

    Немецкий разработчик программного обеспечения SAP AG объявил о приобретении компании Hyrbis, производителя ПО автоматизации коммерции. Как считают в SAP, совместная двух компаний позволит качество обслуживания клиентов на качественно новый уровень благодаря тесному общению в реальном времени через любые устройства и точки взаимодействия.
    Hybris тоже в выигрыше: компания сможет использовать разработки SAP для дальнейшего совершенствования своих продуктов. Но это в будущем, а пока все заняты заменой надписи на фасаде здания и всех бейджей сотрудников – название компании сменилось на Hybris, An SAP Company.

    Aptito интегрируется с TSYS

    Net Element International, специализирующая на электронной коммерции, объявила о завершении интеграции с TSYS облачной платформы для ресторанов Aptito. Мобильный POS-терминал Aptito для планшетов объединяет в себе функции обычного платежного терминала и мобильные заказы, социальные медиа, программы лояльности и др.
    Теперь с помощью одного лишь приложения для iPad можно выбрать блюдо, почитать комментарии, сделать заказ и оплатить банковской картой. Главное не отвлечься и не заиграться в Angry Birds.

    Swiff в сотрудничестве с Affinitas запустит мобильный терминал Mikit в Мексике

    Affinitas, мексиканский провайдер платежных решений, совместно с канадской компанией Swiff запускает в Мексике mPOS-решения, поддерживающие NFC-чипы, ПИН-коды и подписи. Мобильные терминалы будут запущены под брендом Mikit и позволят в любом месте принимать банковские с помощью мобильных устройств.

    Blackbaud запускает мобильное приложение для процессинга кредитных карт

    Американская компания Blackbaud запустила собственное мобильное приложение под названием MobilePay. Приложение доступно на платформах iOS и Android для некоммерческих организаций, пользующихся услугами Blackbaud.
    С помощью приложения и мобильного кард-ридера клиенты Blackbaud смогут принимать платежи по банковским картам, каждый платеж подтверждается подписью покупателя. В итоге, по задумке компании, каждый платеж будет быстрым и удобным. Даже чеки не печатаются, а отправляются клиенту по электронной почте.

    Orange и Visa запускают мобильные платежи в Ботсване

    Мобильный оператор Orange совместно с Visa расширяет возможности сервиса Orange Money в Ботсване. Пользователи сервиса с августа этого года получили возможность оплачивать покупки онлайн и оффлайн со своего счета Orange Money. Для того чтобы воспользоваться новой услугой, пользователям необходимо подать заявление на получение карты Visa Orange Money, которая будет при выпуске привязана к текущему счету.
    Сегодня большинство компаний стараются сделать жизнь своих клиентов проще, придумывая централизованные способы оплаты через специальные приложения-кошельки. Однако не все страны настолько продвинуты, так что решение Orange вполне оправдано.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Карьера специалиста по безопасности



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

    Безопасник сегодня, грубо говоря, может и перекладывать бумажки, и ходить по периметру с радиоборудованием, и составлять планы Disaster Recovery, и непосредственно заниматься исправлением дыр в софте. Специализаций очень много. Все зависит от конкретной организации: ее размера, типов защищаемой информации, используемых технологий и так далее. Понятно, что интереснее всего там, где необходима реальная безопасность, а не фиктивная (бумажная), есть высокий уровень автоматизации.

    Давайте посмотрим, откуда берутся и как получаются такие специалисты.

    Образование

    Разумеется, для того чтобы стать специалистом по информационной безопасности, нужно иметь техническое образование. Лучше всего — специальность, в которой есть слова «автоматизация», «безопасность», «программирование» или «математика». Несколько лет назад очень ценились выпускники исключительно таких ВУЗов как МИФИ, МВТУ, МГУ и МФТИ. За последние годы к ним добавилось достаточно много региональных университетов с примерно аналогичными программами обучения.

    Очень важен английский язык, в особенности — технический. Чем раньше вы его начали учить — тем лучше. Если вы закончили ВУЗ, но ещё не говорите по-английски бегло, стоит записаться на хорошие курсы.

    Ещё в образовании для разных специализаций важно «качать» криптографию (очень хороший базовый курс есть на Курсере) и математику в целом, разбираться в используемом в компании железе (чаще всего речь о телефонии, камерах и так далее), очень хорошо понимать архитектуру сети в теории и знать особенности всего железа на практике, иметь опыт системного администрирования как MS, так и *nix, плюс хотя бы какой-нибудь серверный опыт с HP и IBM. Всё это познаётся на курсах, семинарах для студентов от крупных компаний (они чаще всего бесплатные, например, КРОК регулярно проводит обучение для студентов по разным направлениям, информация доступна здесь. Ряд вещей, вроде умения работать с паяльником — это чисто домашняя практика. Кстати, сам паяльник вам не понадобится, но вот понимание железа на низком уровне — очень даже.

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

    Первая работа

    На выходе из ВУЗа будущий герой безопасности либо никому не нужен (в целом), либо воспринимается как отличный стажер для крупного бизнеса. Причина в том, что всё в работе зависит от конкретного окружения и конкретных угроз. То есть обучиться можно только на практике именно в той компании, где предполагается рост.

    Отсюда три вывода:
    • Хорошо рассчитывать на многолетнюю карьеру в одном месте.
    • Чем раньше вы начнёте знакомиться с будущей компанией — тем лучше. Оптимально — проходить практику прямо в ней.
    • Важно в целом развивать личные качества вроде системного мышления и ответственности — они пригодятся в любых условиях.
    Очень важен наставник-ментор — скорее всего, старший специалист или руководитель, который будет вводить в курс всего, рассказывать про практические особенности и объяснять, какие грабли были раньше. Без него вы обречены на повторное хождение по ним же.

    Дальше в целом есть два частых варианта — либо вы растёте в одной компании. Либо набиваете кучу шишек на первом месте работы, и уже будучи побитым, но опытным, циничным и настороженным, начинаете работать на больший оклад в другом месте.

    Образ жизни и перспективы

    Достаточно частый вопрос от студентов — «кого качать: сисадмина или безопасника»? У опытных людей это сопоставление вызывает улыбку: это как сравнивать тёплое с мягким. На первых порах заработки примерно одинаковые. У безопасника больше шансов на успешную руководящую карьеру, но и больше ответственности: ранняя седина, сердечно-сосудистые заболевания и другие следствия постоянного стресса — это профессиональные риски. Сисадмин, конечно, тоже волнуется, но в случае его провала дело ограничивается головомойкой и восстановлением из бекапа.

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

    Работа специалиста по ИБ часто накладывает отпечаток на образ жизни. Во-первых, профессию не принято афишировать. Несколько ваших знакомых веб-дизайнеров, сисадминов, менеджеров по продажам или-что-там-ещё могут оказаться куда выше в иерархии компании — и на самом деле работать в безопасности. Собственно, я знаю нескольких человек на Хабре, у которых в профиле написана совсем другая должность, нежели в реальности.

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

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

    Пограничные специальности

    При развитии бизнеса (в молодых структурах) очень часто безопасник вырастает или из системного администратора, или из кого-то из разработки, например, проект-менеджера. Просто в какой-то момент становится понятно, что нужен человек, который возьмёт на себя ряд обязанностей — и у кого-то получается легче и проще. Куда реже безопасник получается из финансового аналитика (или чего-то подобного) или юриста (кстати, это одна из немногих гуманитарных профессий, из которой можно перейти в ИБ).

    Из оформившегося специалиста по ИБ может вырасти либо специалист по управлению рисками (это уже финансы), на практике — параноик, показывающий, где и что нужно резервировать, плюс как восстанавливаться в каких ситуациях. Это случается в крупном бизнесе, и в России сейчас тематика Disaster Recovery только начинает приобретать популярность. Возможен и обратный процесс, когда сначала потребуется закрыть риски технической инфраструктуры, а уже потом этот процесс перейдёт в обеспечение безопасности в более широком плане.

    Поддержание в форме

    Каждый день нужно выделять около часа на образование: это единственный шанс оставаться в целом подготовленным к тому, что происходит с технологиями. Нужно постоянно читать конкретику по известным ситуациям взломов, осваивать новые системы — и при этом всё время думать как злоумышленник снаружи. Именно для такого обучения и создавался симулятор Cyber Readiness Challenge: созданная специалистами Symantec по ИБ с большим опытом, моделируемая сеть корпорации содержит характерные детали для многих крупных сетей.

    Сложность в том, что быть готовым ко всему просто нельзя. Если лет 15 назад действительно можно было знать все без исключения особенности своей технической среды, то сейчас хакеры атакующей группы (например, конкурентов или, что куда чаще — мошенников) будут по умолчанию более подготовленными в конкретных технологиях. Это значит, что вам либо нужно иметь в своём штате специалистов-виртуозов с узкими специализациями, либо знать таковых, чтобы в случае проблем иметь возможность быстро с ними посоветоваться или привлечь для решения проблемы.

    Разумеется, в форме нужно поддерживать не только себя, но и свой отдел, а также вообще всех людей в компании. Здесь два простых принципа — аудиты-проверки и учебные тревоги.

    Напоследок

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

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

    Этот турнир поможет не только дать знания участникам, но и получит традиционную огласку в СМИ (вот отчёты с прошлых, например). Ожидаем эффекта, который будет ощутимо полезен для сферы.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Перевод] Понимание типов сервисов в AngularJS (constant, value, factory, service, provider)

    Ангуляр поставляется с различными видами служб или сервисов, каждый из которых применяется в своей ситуации.
    Имейте в виду, что сервисы, не зависимо от типа, это всегда синглтоны (одиночки).

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

    Перейдем к типам сервисов

    Constant

    <code class="javascript">app.constant('fooConfig', {
      config1: true,
      config2: "Default config2"
    });
    </code>
    Константа часто используется для конфигурации по умолчанию в директивах. Так что если создаете директиву, и хотите помимо настройки иметь возможность передать ей некоторые стандартные параметры, константа — хороший способ сделать это.

    Значение константы задается при определении и не может быть изменено другим путем. Значением константы может быть примитив или объект.

    Value

    <code class="javascript">app.value('fooConfig', {
      config1: true,
      config2: "Default config2 but it can changes"
    });
    </code>
    Переменная подобна константе, но может быть изменена. Она часто используется для настройки директив. Переменная подобна усеченной версии фабрики, только содержит значения, которые не могут быть вычислены в самом сервисе.

    Factory

    <code class="javascript">app.factory('foo', function() {
      var thisIsPrivate = "Private";
      function getPrivate() {
        return thisIsPrivate;
      }
    
      return {
        variable: "This is public",
        getPrivate: getPrivate
      };
    });
    
    // или...
    
    app.factory('bar', function(a) {
      return a * 2;
    });
    </code>
    Фабрика является наиболее часто используемым сервисом. Так же она самая простая для понимания.

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

    Как упоминал выше, все типы это синглтоны, так что, если мы изменим
    foo.variable в одном месте, в других местах она тоже изменится.

    Service

    <code class="javascript">app.service('foo', function() { var thisIsPrivate = "Private"; this.variable = "This is public"; this.getPrivate = function() { return thisIsPrivate; }; }); </code>Сервис (не путайте общее название с конкретным типом) работает так же как фабрика. Разница в том, что сервис использует конструктор, поэтому, когда используете его в первый раз, он выполнит new Foo();
    для создания экземпляра объекта. Имейте в виду, что этот же объект вернется и в других местах, если использовать там этот сервис.

    Фактически сервис эквивалентен следующему коду:

    <code class="javascript">app.factory('foo2', function() {
      return new Foobar();
    });
    
    function Foobar() {
      var thisIsPrivate = "Private";
      this.variable = "This is public";
      this.getPrivate = function() {
        return thisIsPrivate;
      };
    }
    </code>
    Foobar является классом, и мы создаем его экземпляр на нашей фабрике, используем его первый раз, а затем возвращаем. Как и сервис, экземпляр класса Foobar
    будет создан только однажды и в следующий раз фабрика вернет этот же экземпляр снова.

    Если у нас уже есть класс, и мы хотим использовать его в нашем сервисе, можем сделать так:

    <code class="javascript">app.service('foo3', Foobar);
    </code>

    Provider

    Провайдер это фабрика, настроенная особым образом. Фактически фабрика из последних примеров будет выглядеть как-то так:

    <code class="javascript">app.provider('foo', function() {
    
      return {
    
        $get: function() {
          var thisIsPrivate = "Private";
          function getPrivate() {
            return thisIsPrivate;
          }
    
          return {
            variable: "This is public",
            getPrivate: getPrivate
          };
        }
    
      };
    
    });
    </code>
    Провайдер ожидает функцию
    $get, которая будет тем, что мы внедряем в другие части нашего приложения. Поэтому, когда мы внедряем foo 
    в контроллер, то внедряется функция
    $get

    Почему нужно использовать эту форму, когда фабрика гораздо проще? Потому что провайдер можно настроить в конфигурационной функции. Так что можно сделать что-то вроде этого:

    <code class="javascript">app.provider('foo', function() { var thisIsPrivate = "Private"; return { setPrivate: function(newVal) { thisIsPrivate = newVal; }, $get: function() { function getPrivate() { return thisIsPrivate; } return { variable: "This is public", getPrivate: getPrivate }; } }; }); app.config(function(fooProvider) { fooProvider.setPrivate('New value from config'); }); </code>Здесь мы вынесли thisIsPrivate
    за пределы функции
    $get, а затем создали функцию setPrivate
    , чтобы иметь возможность изменить
    thisIsPrivate
    в функции конфигурации. Почему нужно это делать? Не проще ли просто добавить сеттер на фабрике? Тут другая цель.

    Мы хотим внедрить определенный объект, но хотим иметь способ настроить его для своих нужд. Например: для сервиса-обертки ресурса, использующего JSONP, хотим иметь возможность настроить URL, который будет использоваться нами или сторонними сервисами, такими как
    restangular. Провайдер позволяет нам настроить предварительно его для наших целей.

    Обратите внимание, что в конфигурационной функции нужно указать в качестве имени nameProvider
    , а не
    name. name
    указывается во всех других случаях.

    Видя это, вспоминаем, что уже настраивали некоторые сервисы в наших приложениях, например, в
    $routeProvider
    и
    $locationProvider
    настраивают роутинг и html5mode соответственно.

    Бонус 1: Декоратор

    Итак, вы решили, что какому-то сервису
    foo, не хватает функции greet
    и вы хотите ее добавить. Стоит ли изменять фабрику? Нет! Можно ее декорировать:

    <code class="javascript">app.config(function($provide) {
      $provide.decorator('foo', function($delegate) {
        $delegate.greet = function() {
          return "Hello, I am a new function of 'foo'";
        };
    
        return $delegate;
      });
    });
    </code>
    $provide
    это то, что Ангуляр использует для создания всех внутренних сервисов. Мы можем использовать его вручную, если хотим, или просто использовать функции, предоставляемые в наших модулях (необходимо использовать
    $provide
    для декорирования).
    $provide
    имеет функцию,
    decorator, которая позволяет нам декорировать наши сервисы. Она получает имя декорируемого сервиса, а колбэк получает $delegate
    , который является оригинальным экземпляром сервиса.

    Здесь мы можем делать все что захотим хотим, чтобы декорировать наш сервис. В нашем случае, мы добавили функцию
    greet в оригинальный сервис. Затем вернули новый модифицированный сервис.

    Теперь, при использовании, он будет иметь новую функцию greet
    .

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

    Примечание: Константу декорировать нельзя.

    Бонус 2: создание новых экземпляров

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

    <code class="javascript">// Наш класс
    function Person( json ) {
      angular.extend(this, json);
    }
    
    Person.prototype = {
      update: function() {
        // Обновляем (В реальном коде :P)
        this.name = "Dave";
        this.country = "Canada";
      }
    };
    
    Person.getById = function( id ) {
      // Делаем что-то, чтобы получить Person по id
      return new Person({
        name: "Jesus",
        country: "Spain"
      });
    };
    
    // Наша фабрика
    app.factory('personService', function() {
      return {
        getById: Person.getById
      };
    });
    </code>
    Здесь создаем объект
    Person, который получает некоторые JSON данные для инициализации объекта. Затем создали функцию в нашем прототипе (функции в прототипе для экземпляров Person
    ) и функции непосредственно в
    Person (подобные функции класса).

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

    Каждый раз, когда мы вызываем
    personService.getById мы создаем новый объект Person
    , так что можно использовать этот сервис в различных контроллерах и даже тогда, когда фабрика является синглтоном, она создает новые объекты.

    Респект Джошу Дэвиду Миллеру за его пример.

    Бонус 3: CoffeeScript

    CoffeeScript можно удобно сочетать с сервисами, поскольку они обеспечивают более симпатичный способ создания классов. Давайте рассмотрим Бонусный пример 2 с использованием CoffeeScript:

    <code class="javascript">app.controller 'MainCtrl', ($scope, personService) ->
      $scope.aPerson = personService.getById(1)
    
    app.controller 'SecondCtrl', ($scope, personService) ->
      $scope.aPerson = personService.getById(2)
      $scope.updateIt = () ->
        $scope.aPerson.update()
    
    class Person
    
      constructor: (json) ->
        angular.extend @, json
    
      update: () ->
        @name = "Dave"
        @country = "Canada"
    
      @getById: (id) ->
        new Person
          name: "Jesus"
          country: "Spain"
    
    app.factory 'personService', () ->
      {
        getById: Person.getById
      }
    </code>
    Сейчас он выглядит красивее, по моему скромному мнению.
    Сейчас он выглядит ужаснее по скромному мнению переводчика.

    Заключение

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Удобный интерфейс Хабра? #2

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

    image

    Итак, исходные данные:

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

    Навигация и хабралента

    Мне не нравятся навигационные меню на Хабре. Они не имеют единого стиля и логики, плюс ко всему приходится делать слишком много кликов в процессе серфинга.

    image

    Меню пользователя странно сгруппировано, а свободного пространства в шапке столько, что можно играть в футбол:

    image

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

    Сокращаем пустое пространство, главное меню упрощаем: функционал кучи ссылок второго уровня можно перенести в панель настроек, к примеру, управлять отображением хабраленты можно включая/отключая нужный тип записей.

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

    Еще хотелось немного упростить некоторые элементы, привести их к единому виду. В итоге вот, что получилось:

    image

    Крупнее

    Страница поста

    image

    Крупнее

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

    image

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [recovery mode] Арканоид с джойстиком на телефоне

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

    И я вспомнил о технологии управления любыми экранами с мобильного телефона, которую описал в предыдущей статье. Цель в той статье была достигнута но практического применения ноль.

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



    Сама игра теперь лежит на главной странице библиотеки.

    Собственно весь код как и всегда лежит на гитхабе.

    Весь основной код управления (коего как вы поняли не много) сконцентрирован в js файле example/js/main.js, всё что не относится к управлению, а относится лишь к игре лежит в файле example/js/game.js

    Вкратце, используя API библиотеки remoteall, мы просто принимаем сигналы от джойстика и передаём их в игру в виде изменения статуса глобальных переменных (игра взята в интернете, а ссылка потеряна, потому за код и логику игры я отвечать не могу)
    Весь код настройки этого взаимодействия укладывается в 30 строк
    <code>ra.on('recive_code', function (data, session_id) {
        if( (data.button_code=='LENTER' || data.button_code=='RENTER') && data.event_name =='button_down'){ //reset game
            restartGame()
            return
        }
    
        switch (data.event_name) {
            case 'button_down':
                switch (data.button_code) {
                    case 'LEFT': // 'Left' key
                        bLeftBut = true;
                        break;
                    case 'RIGHT': // 'Right' key
                        bRightBut = true;
                        break;
                }
                break;
            case 'button_up':
    
                switch (data.button_code) {
                    case 'LEFT': // 'Left' key
                        bLeftBut = false;
                        break;
                    case 'RIGHT': // 'Right' key
                        bRightBut = false;
                        break;
    
                }
    
                break;
        }
    })
    </code>


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

    И сразу есть вопросы к хабралюдям:

    • По вашему мнению, есть ли вообще потенциал и может ли данная технология применяться в реальной разработке игр/приложений?
    • Как еще можно применить такого рода сущность мобильник-джойстик с условием отсутствия обратной связи (нет кнопок ощущаемых пальцами) ?

    Всем спасибо, хороших выходных.

    UDP:
    Сервер должен справиться с кучей запросов и веб сокетов, но всё же вероятность что node.js не справится примерно 5% :)

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Коротко о новом: Samsung запустила в массовое производство первую в отрасли 3D Vertical NAND флэш-память с вертикальной компоновкой

    Доброй пятницы, Хабр!

    На прошлой неделе Samsung Electronics объявила о начале серийного выпуска флэш-памяти с объемной компоновкой 3D Vertical NAND (V-NAND), которая призвана сделать прорыв и обеспечить возможности для дальнейшего уменьшения NAND Flash. Новая 3D V-NAND флэш-память будет использоваться в широком спектре потребительской электроники и корпоративных решений, в том числе, во встроенных NAND и SSD-накопителях.

    image

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

    Новые чипы Samsung V-NAND решают вышеперечисленные технические проблемы путем достижения нового уровня инноваций в цепях, структуре и производственном процессе. Samsung V-NAND обеспечивает плотность 128 гигабит в одном чипе, используя фирменную структуру ячеек на основе новой архитектуры 3D Charge Trap Flash (CTF) и технологии вертикальных соединений, связывающих ячейки в объемный массив.

    image

    Чтобы достичь нового уровня надежности флэш-памяти, компания Samsung обновила свою CTF-архитектуру, впервые разработанную еще в 2006 году. В новой архитектуре NAND Flash электрический заряд временно помещается в «ячейку ожидания» непроводящего слоя флэш-памяти, который состоит из нитрида кремния (SiN), вместо традиционно используемых плавающих затворов, что позволило предотвратить помехи во время работы соседних ячеек.

    Новые V-NAND чипы не только демонстрируют повышенные показатели надежности работы (в два раза, как минимум и в десять раз — максимум), но и в два раза большую скорость записи по сравнению с обычной флэш-памятью 10-нм класса на основе плавающих затворов.

    Кроме того, одним из наиболее важных технологических достижений новой памяти Samsung V-NAND является тот факт, что данный вертикальный процесс обмена данными позволяет формировать в одном кристалле более, чем 24 слоя ячеек, благодаря использованию специальной технологии травления, которая соединяет слои электронным путем, пробивая отверстия с самого высокого до самого низкого слоя.

    image

    Спустя почти десять лет упорных исследований в сфере NAND флэш-памяти вертикальной компоновки, к настоящему моменту Samsung имеет в наличии более 300 запатентованных технологий объемной 3D памяти по всему миру.

    Согласно данным исследовательской компании IHS iSuppli, к концу 2016 года глобальный рынок NAND флэш-памяти достигнет уровня прибыли около $30,8 млрд., что должно составить 11% среднегодового роста в сравнении текущим годом (около $23,6 млрд.).

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Новая страница Trending на GitHub

    13 августа GitHub порадовал пользователей очередным приятным нововведением — в этот раз сделан шаг в сторону дальнейшей социализации.
    Был выпущен новый способ просматривать, что находится в тренде на сервисе с удобством фильтрации по временному периоду, трендовым проектам, разработчикам и языкам программирования.

    Новая страница GitHub Trending Page пересчитывает данные восемь раз в сутки, собирая и анализируя статистику за последний день, неделю и месяц. Используя выпадающий список можно отфильтровать информацию по необходимому периоду.
    Языки программирования ранжированы, а репозитории и разработчики по-умолчанию выводятся независимо от языка. Если вы залогинены, то увидите трендовые языки, которые GitHub базирует на ваших избранных (starred) репозиториях. В противном случае вы сможете ознакомиться с самыми популярными языками всего GitHub.
    Популярность языков всегда базируется на репозиториях. Даже если вы просматриваете вкладку Trending Developers их ранжирование проводится на основании языка их самых трендовых репозиториев.



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

    Источник — Explore what is Trending on GitHub

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Правило 20% больше не действует в Google

    Пресловутое «правило 20%» когда-то приводилось в пример как эффективный подход к инновациям в Google. В соответствии с ним, каждый сотрудник компании имел право 20% рабочего времени, то есть один день в неделю, посвящать сторонним проектам, не связанным с основной деятельностью.

    Благодаря правилу 20% в своё время появились на свет такие проекты как Gmail и AdSense, а также сотни мелких проектов, многие из которых ушли в Open Source. Правило 20% — самое знаменитое правило Google, которое чаще всего копировали другие компании.

    Однако, по словам нескольких бывших сотрудников Google, правило двадцати процентов уже не практикуется в компании. Его принесли в жертву эффективности, в соответствии с новой корпоративной стратегией.

    Отмена « 20%» началась с того, что 2012 году было решено, что разрешение на сторонние проекты сотрудникам теперь нужно будет получать у менеджера. Таким образом, отменялась предыдущая норма, что это неотъемлемое право каждого сотрудника.

    Потом в компании Google сформировали мощный аналитический отдел, который анализировал производительность персонала. Чтобы работать с максимальной эффективностью, сотрудникам нужно уделять основному проекту 100% своего времени, так что очень немногие решались подать заявку на открытие проекта по «правилу 20%», и это не поощрялось менеджерами.

    Новая политика компании связана с приходом на пост исполнительного директора Ларри Пейджа в 2011 году. Он объявил, что компания должна сосредоточить больше ресурсов на меньшем количестве проектов, после чего начались периодические «зачистки» — удаление бесперспективных и «лишних» сервисов, на которые неэффективно расходовались трудовые ресурсы. В числе прочих, был закрыт и проект Google Labs, под крышей которого концентрировалось множество маленьких проектов, создававшихся в «свободное время» сотрудников.

    Конечно, инновации в Google продолжаются и теперь, но они приобрели более контролируемый характер, а стала более эффективной. В рамках новой организационной структуры — научно-исследовательского центра Google X — идёт работа над такими проектами как Google Glass и беспилотные автомобили. Подобные проекты невозможно создать в «20% свободного времени».

    Вопрос только в том, что теперь делать многочисленным компаниям, которые скопировали у Google её знаменитое правило. По слухам, среди них Apple, LinkedIn, 3M и многие другие.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Функциональные возможности ETERNUS DX

    Уважаемые хабрапользователи, представляем действительно толковую статью, посвященную актуальным аспектам интеграции современных дисковых систем ETERNUS DX в ИТ-среду.



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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    ARM-ы для самых маленьких: который час?



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


    Тактовая частота – основной источник «рабочей силы» в процессоре, ее генератор можно сравнить с сердцем у человека. В разных компонентах процессора может использоваться разная частота, которая, тем не менее, зарождается обычно в одном и том же кристалле (или резонаторе).

    Большинство процессоров имеют встроенный резонатор и возможность подключить внешний резонатор или кристалл. Зачем это сделано? В основном, для удешевления процессора. Встроенный резонатор типично имеет погрешность около 1%, чего может хватить для многих задач, но есть еще больше задач, для которых такая точность неприемлема. В самом деле, если мы будем, например, считать время на встроенном резонаторе, то погрешность за сутки может достигнуть 14 минут. Если вы передаете пакет по сети где-то раз в полчаса – это совершенно не критичная погрешность. Другое дело, если вы делаете будильник.


    (изображение из LPC111x User Manual)

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

    ? Основная частота

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

    Во-первых, это IRC – внутренний резонатор. Рабочая частота – 12 МГц (на самом деле, можно тюнинговать в небольших пределах), погрешность — около 1%. Именно отсюда генерируется тактовая частота процессора в момент старта, так что весь загрузочный код выполняется при тактовой частоте в 12 МГц. Вариант максимально простой (вам вообще ничего не надо делать, чтобы он работал), не требует дополнительных внешних компонентов. К сожалению, имеет свои проблемы: резонатор, как я уже упоминал, несколько неточен, кроме того, нам не особенно интересно гонять ядро на 12 МГц, когда оно отлично работает на 50 МГц.

    Во-вторых, основную частоту можно задать еще с одного внутреннего генератора – watchdog oscillator, который обычно используется для работы watchdog. Этот осциллятор работает на скоростях (программно настраиваемо) от 9,4 кГц до 2,3 МГц с погрешностью ±40%, — казалось бы, не лучшее решение для основной частоты. С другой стороны – это именно то замечательное и энергоэффективное решение, если вам нужно перевести ядро в спящий режим, при этом оставив какую-то часть периферии рабочей.

    В-третьих, мы можем получить основную частоту из системного осциллятора до или после ФАПЧ. Не будем сейчас вникать в специфику работы ФАПЧ, так как это достаточно объемная тема. Интересующимся советую изучить раздел «3.11 System PLL functional description».

    ? Системный осциллятор

    Системный осциллятор – это та часть процессора, которая не будет работать без аппаратных модификаций, в нем отсутствует основная рабочая сила осциллятора – кристалл (или кварцевый резонатор), который необходимо подключить снаружи, для чего на любом современном процессоре есть пины XTALIN/XTALOUT.

    Конкретно LPC1114 (впрочем, как и остальные процессоры линейки LPC111x) поддерживает кристаллы с частотой осцилляции от 1 МГц до 25 МГц. Помимо самого кристалла, вам также понадобятся два конденсатора, значения которых зависят от параметров выбранного кристалла. Тут я отсылаю вас к datasheet, где в разделе 12.3 (XTAL input) есть и схема подключения, и таблица с рекомендованными емкостями конденсаторов. В тестовой схеме я пробовал использовать кристалл с частотой 12 МГц, емкостью нагрузки 20 пФ и двумя конденсаторами на 39 пФ, но этот режим работы далее рассматриваться не будет.

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

    Системный осциллятор можно использовать непосредственно как генератор основной частоты, или же предварительно пропустить его через ФАПЧ.

    ? ФАПЧ

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

    Настройка параметров ФАПЧ потенциально опасна для внутренностей процессора, потому я рекомендую NXP-шную утилиту (успешно конвертируется и работает в Google Drive) для подбора необходимых параметров, просто задайте частоту осциллятора на входе и итоговую частоту, которую хотите получить, и она рассчитает возможные варианты.

    В сети есть интересная заметка о том, как поднять частоту IRC для генерации 50 МГц на выходе ФАПЧ, но для отладки этого результата вам понадобится осциллометр.

    ? Системная частота

    Обычно ядро (то, что Cortex-M0) работает на основной частоте, но, при необходимости, основную частоту можно разделить (на значение вплоть до 255), получив в итоге системную частоту. Помимо непосредственно ядра, на этой частоте будут работать флеш-память, RAM и вся периферия, за исключением SPI и UART. Имейте в виду, что максимальная частота тут – это 50 МГц.

    ? А что же со SPI и UART?

    Из-за специфики этих интерфейсов у них есть свои выделенные делители частоты, например, у UART он позволяет выбрать необходимый битрейт.

    Несмотря на некоторую неочевидность схемы, на вход делителя попадает не основная, а системная частота.

    Расчет делителя для битрейта – достаточно сложная задача, потому в очередной раз отправляю вас в инструкцию – «13.5.15 UART Fractional Divider Register (U0FDR — 0x4000 8028)». Там есть и формула расчета, и объяснение дополнительного дробного аргумента, а также блок-схема для поиска нужных параметров для заданного битрейта и пара примеров.

    У SPI все как-то существенно проще, скорее всего потому, что мастер на шине задает частоту, и остальные устройства работают на ней – заочной синхронизации не требуется. Так что единственное, что мы можем сделать – это задать делитель. Важный момент – когда процессор работает в мастер-режиме, то минимальный делитель – 2, т.е., при частоте системной частоты в 48 МГц скорость передачи данных на SPI будет 24 МГц.

    UPD: как верно заметил valeriyk, этот делитель не единственное, что влияет на выходную частоту. У SPI, например, несущая частота расчитывается по формуле:
    PCLK / (CPSDVSR * (SCR + 1))
    , где PCLK — это частота периферии; CPSDVSR — «предделитель»; SCR — количество тактов предделителя на один бит вывода.

    ? Watchdog на страже жизнедеятельности

    Watchdog по своей специфике — компонент изолированный. Поэтому, в качестве ведущей частоты можно использовать системную, IRC или отдельный осциллятор. Точно так же, у watchdog есть свой выделенный делитель.

    Зачем для watchdog нужен отдельный тактовый генератор? Если программа случайно поломает основной генератор, конечно же! Тогда у нее все еще будет шанс быть перезагруженной по таймеру watchdog.

    ? На выход

    Наконец, процессор может генерировать выходной сигнал тактовой частоты на пине CLKOUT (одна из альтернативных функций у GPIO 0.1). В качестве ведущей частоты мы можем использовать любую из доступных нам: из осцилляторов (IRC, системного или watchdog) или системную частоту (после ФАПЧ, если он включен). Ну и, конечно, свой делитель.

    Немного о mbed

    Мы детально рассмотрели процесс генерации тактовой частоты в LPC1114, но что же с LPC1768? На самом деле, у каждой линейки процессоров может быть (и скорее всего будет свой особый подход, потому инструкцию по этой теме надо изучить предельно внимательно. В LPC1768 также есть внутренний осциллятор – IRC, но работает он на частоте 12 МГц. Помимо него есть основной (main) осциллятор, идентичный системному осциллятору. На mbed к нему подключен кристалл на 12 МГц. Наконец, есть осциллятор часов реального времени (RTC), но кристалл к нему не подключен.

    Также, помимо основного ФАПЧ, есть дополнительный, который используется для генерации рабочей частоты USB. Все компоненты периферии имеют независимые настраиваемые делители относительно рабочей частоты.

    Практические нюансы изменения частоты

    Изменение рабочей тактовой частоты влечет за собой несколько последствий. Самое очевидное — необходимость перенастраивать таймеры. Также, потребуется переинициализация периферии, работающей с протоколами где важно зафиксировать несущую частоту (UART, USB). Наконец, количество тактов для доступа к флеш-памяти тоже играет важную роль. У LPC1114 значение по умолчанию — 3 такта (рабочая частота до 50 МГц, см. документацию по регистру FLASHCFG), чего вполне хватает для наших задач. Но у LPC1768 значение по умолчанию — 4 такта, с рабочей частотой до 80 МГц, чего нам будет недостаточно.

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

    За работу!

    Теперь у нас есть необходимый теоретический багаж, и мы готовы применить полученные знания на практике – заставить светодиод мигать детерминировано, 1 раз в секунду.

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

    Сложный момент с CMSIS состоит в том, что иногда не совсем понятно, где найти актуальную версию. Базовый набор файлов можно скачать непосредственно у ARM, на момент написания там доступна версия 3.01. Помимо заголовочных файлов, ARM предоставляет библиотеку для разноплановых сложных расчетов на DSP (которого в нашем железе все равно нет). Хуже обстоит дело с драйверами от конкретных производителей. У NXP, например, CMSIS для LPC1114 основан на CMSIS 1.30, а для LPC1768 – на 2.10. Более того, в наборе драйверов периферии есть явные ошибки в коде. А уж драйверы для чипов TI приходится основательно искать в гугле.

    Из этого можно сделать два важных вывода: во-первых, код драйверов почти весь открыт, так что «доверяй, но проверяй»: инструкция и даташит — это ваша основная литература по работе с периферией. Во-вторых, в драйверах нет почти ничего, что нельзя было бы написать самому, т.е., это отличный и, зачастую, рабочий справочный материал. Главное – не забывать относиться к нему критически, если что-то выглядит странно – раскуривайте инструкцию по процессору.

    Исходный код теперь несколько более структурирован. Хотя в результате он существенно вырос в количестве фалов, теперь намного проще поддерживать несколько разных платформ. Исходники для сегодняшнего примера доступны на GitHub: farcaller/arm-demos (pull-реквесты для новых архитектур приветствуются!).

    Дерево исходников еще не до конца причесано, в частности, я не избавился от примитивных
    boot.s
    и
    memmap.ld
    . Следующая часть будет целиком посвящена вопросам компоновщика (включая сборку мусора и правильную инициализацию .data и .bss), где мы займемся добиванием до конца всех спорных моментов. Весь код разбит на три категории: в
    app/
    находятся файлы «приложения» – непосредственно рабочий код примера. Он оформлен в стиле arduino, через функции
    setup()
    и
    loop()
    . В
    platform/
    хранятся описания разных платформ и платформозависимые функции (кроме
    platform/common
    , файлы которого линкуются во все платформы). Наконец, в
    cpu/
    находятся CMSIS для конкретных процессоров.

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

    Работа по часам

    Для реализации нашей задачи (напомню, нам надо мигать светодиодом ровно раз в секунду) нам пригодился бы какой-то таймер. К счастью, таймеров в LPC-шных процессорах сразу несколько, мы будем работать с самым унифицированным – SysTick. Этот таймер описан непосредственно в CMSIS, т.е., есть большая вероятность того, что он будет и в любом другом процессоре. Его предполагается использовать для измерения квантов времени при переключении задач в ОС, но ничего не мешает использовать его для простых задач.

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

    platform/common/systick.c
    :
    <code class="cpp">void platform_systick_setup(unsigned int load)
    {
        SysTick->CTRL = 0x04;
        SysTick->LOAD = load < 0xffffff ? load : 0xffffff;
        SysTick->VAL = 0;
        SysTick->CTRL = 0x05;
    }
    </code>

    Для начала о синтаксисе. Эти замечательные структуры доступны нам из CMSIS, больше не надо запоминать, где находятся регистры, да и доступ к полям реализуется существенно нагляднее.

    Для инициализации таймера мы записываем 4 в регистр контроля. Это выключает таймер, если он был включен, выключает прерывание и переводит SysTick на использование частоты процессора (напоминаю, что по умолчанию — это 12 МГц). Далее мы загружаем стартовую точку отсчета в регистр SYST_RVR, ограничивая максимум — 16777215, сбрасываем текущее значение регистра в ноль и запускаем таймер.

    Теперь о том, как нам подождать одну секунду:
    <code class="cpp">void platform_systick_wait()
    {
        volatile int i;
        i = SysTick->CTRL;
        while((i & 0x00010000) == 0) {
           i = SysTick->CTRL;
        }
    }
    </code>

    Мы считываем значение COUNTFLAG из регистра SYST_CSR. COUNTFLAG выставляется в единицу, когда счетчик идет на новый круг, и сбрасывается в ноль при чтении. Таким образом, мы будем в цикле, пока счетчик не переполнится.

    Заглянем в другие файлы нашего проекта.
    app/systick-blink.c
    :
    <code class="cpp">#include "platform.h"
    
    void setup()
    {
        platform_led_setup();
    #if PLATFORM == MBED
        platform_systick_setup(4000000);
    #elif PLATFORM == PROTOBOARD
        platform_systick_setup(12000000);
    #else
        #error Unknown platform
    #endif
    }
    
    void loop()
    {
        platform_led_toggle(1);
        platform_systick_wait();
        platform_led_toggle(0);
        platform_systick_wait();
    }
    </code>

    Тут все достаточно наглядно. Инициализируем «драйвер» светодиода и таймера, и в цикле включаем-выключаем светодиод с задержкой. В зависимости от платформы, используем разное стартовое значение таймера (IRC на mbed и protoboard у нас работают на разных частотах). А как же работает код самого светодиода?

    platform/protoboard/led.c
    :
    <code class="cpp">#include "LPC11xx.h"
    
    #define LED_PIN (1<<9)
    
    void platform_led_setup()
    {
        LPC_GPIO1->DIR |= LED_PIN;
    }
    
    void platform_led_toggle(int on)
    {
        LPC_GPIO1->MASKED_ACCESS[LED_PIN] = on ? LED_PIN : 0;
    }
    </code>

    Как видите, с CMSIS все стало действительно читабельнее. Единственный интересный момент — это то, что вместо общего регистра GPIO мы сейчас используем регистр с маской. Он позволяет устанавливать биты GPIO для конкретных пинов с маской, т.е., можно просто писать нужное значение, не думая о том, что надо сохранять состояние соседних пинов. Детальнее (и в картинках) об этом можно прочитать в инструкции: «12.4.1 Write/read data operation».

    Для сравнения вот код для mbed.
    platform/mbed/led.c
    :
    <code class="cpp">#include "LPC17xx.h"
    
    #define LED_PIN       (1<<18)
    #define LED_PIN_IN_B2 (1<<2)
    
    void platform_led_setup()
    {
        LPC_GPIO1->FIODIR |= LED_PIN;
    }
    
    void platform_led_toggle(int on)
    {
        LPC_GPIO1->FIOMASK2 |= ~LED_PIN_IN_B2;
        if (on) {
            LPC_GPIO1->FIOSET2 = LED_PIN_IN_B2;
        } else {
            LPC_GPIO1->FIOCLR2 = LED_PIN_IN_B2;
        }
    }
    </code>

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

    Собрать проект можно командой
    rake build_protoboard
    или
    rake build_mbed
    . Можно даже сразу прошить устройство:
    rake upload_protoboard TTY=/dev/ftdi/tty/device
    или
    rake upload_mbed MOUNT=/Volumes/MBED
    соответственно. Сейчас светодиоды мигают идентично на обоих устройствах.

    Поиграем частотой?

    Вроде бы мы и решили поставленную задачу — светодиод мигает с корректным интервалом, но что-то еще осталось за кадром. Максимальная рабочая частота LPC1114 — 50 МГц, а у LPC1768 и того больше — 100 МГц, получается, мы гоняем их едва ли в треть силы!

    Настало время заняться правильной инициализацией платформы.
    platform/protoboard/init.c
    :
    <code class="cpp">#define CLOCK_MODE_IRC          0 // 12 MHz
    #define CLOCK_MODE_IRC_WITH_PLL 1 // 48 MHz
    #define CLOCK_MODE_SYS_WITH_PLL 2 // 48 MHz with external 12MHz crystal
    
    #define CLOCK_MODE CLOCK_MODE_IRC
    </code>

    В исходном коде доступны три шаблона для LPC1114: стандартные 12 МГц от IRC, 48 МГц от IRC, пропущенного через ФАПЧ, и 48 МГц от системного осциллятора, пропущенного через ФАПЧ. Последний вариант требует дополнительной аппаратной поддержки, но мы рассматриваем его, так как это очень актуальный режим использования.

    <code class="cpp">void platform_init()
    {
    // set up system oscillator and toggle PLL to point at it
    #if CLOCK_MODE == CLOCK_MODE_SYS_WITH_PLL
        int i;
    
        // power up system oscillator
        LPC_SYSCON->PDRUNCFG &= ~(1 << 5);
    
        // oscillator is not bypassed, runs at 1-20MHz range
        LPC_SYSCON->SYSOSCCTRL = 0;
    
        // allow circutry to settle down
        for (i = 0; i < 200; ++i)
            __NOP();
    
        // set PLL clock source to system oscillator
        LPC_SYSCON->SYSPLLCLKSEL = 1;
    
        // wait for PLL clock source to be updated
        LPC_SYSCON->SYSPLLCLKUEN = 1;
        LPC_SYSCON->SYSPLLCLKUEN = 0;
        LPC_SYSCON->SYSPLLCLKUEN = 1;
        while (!(LPC_SYSCON->SYSPLLCLKUEN & 1))
            ;
    #endif
    </code>

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

    После первичной инициализации следует сделать небольшую задержку. Далее мы переводим ФАПЧ на работу от системного осциллятора (вместо IRC), для этого существует интересный механизм: пишем 0, пишем 1, ждем — регистр начнет возвращать 1.

    <code class="cpp">// set up PLL if it's used
    #if CLOCK_MODE == CLOCK_MODE_IRC_WITH_PLL || CLOCK_MODE == CLOCK_MODE_SYS_WITH_PLL
        // set up PLL dividers
        LPC_SYSCON->SYSPLLCTRL = 0x23; // M = 3, P = 12MHz
                                       // PLLout = 12MHz * (M+1) / P = 48MHz
    
        // power up PLL
        LPC_SYSCON->PDRUNCFG &= ~(1 << 7);
    
        // wait until PLL is locked
        while (!(LPC_SYSCON->SYSPLLSTAT & 1))
            ;
    
        // switch main clock to be driven from PLL
        LPC_SYSCON->MAINCLKSEL = 3;
    
        // wait for main clock source to be updated
        LPC_SYSCON->MAINCLKUEN = 1;
        LPC_SYSCON->MAINCLKUEN = 0;
        LPC_SYSCON->MAINCLKUEN = 1;
        while (!(LPC_SYSCON->MAINCLKUEN & 1))
            ;
    #endif
    </code>

    Вторая часть инициализирует ФАПЧ, который на данном этапе получает на входе сигнал или от IRC, или от системного осциллятора. Настраиваем делители по формуле из инструкции, включаем ФАПЧ и ждем, пока он заблокируется. Основная частота после загрузки работает от IRC, переводим ее на работу от выхода ФАПЧ и ждем, пока это изменение «устаканится».

    На 48 МГц для SysTick нам понадобится 48000000 циклов, но это больше его максимального значения. Один из вариантов решения — ждать несколько циклов таймера, что реализовано в функции
    platform_systick_wait_loop
    (другим вариантом было бы использовать 32-разрядный таймер CT32B0).

    У LPC1768 код, опять же, в целом похожий. Тут важный момент в том, что на выходе из PLL должно быть не менее 275 МГц, когда на входе в процессор — не более 100 МГц. В общем, внимательно проверяем делители. Также важно отметить, что мы повышаем количество тактов, необходимых для доступа к флеш-памяти, потому что мы будем работать на частоте выче чем значение по умолчанию.

    platform/mbed/init.c
    :
    <code class="cpp">// if we go for clock > 80 MHz, we need to set up flash access time
    LPC_SC->FLASHCFG = (LPC_SC->FLASHCFG & 0xFFF) | 0x4000; // 4 cpu clocks
    </code>

    Код, приведенный в примере, актуален только для LPC1768 на mbed, так как привязан к конкретной частоте кристалла. Более того, если вы работаете с LPC1768 «напрямую», то его загрузчик стартует с IRC с включенным ФАПЧ, так что в своем инициализаторе его перед настройкой необходимо выключить.

    Подводя итоги

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

    До меня доехала коробка со Stellaris LaunchPad, я подумаю над тем, как лучше всего будет добавить еще одну архитектуру, не раздувая повествование. В любом случае, LPC1114 становится основным целевым процессором, все примеры мы сначала будем обкатывать на нем.

    Приношу свои извинения за «многобукаф», далее постараюсь писать более содержательно.

    P.S. Как всегда, большое спасибо pfactum за вычитку текста и бесценные комментарии по электромеханике. И за то, что объяснил про ФАПЧ :-).

    Лицензия Creative Commons Это произведение доступно по лицензии Creative Commons «Attribution-NonCommercial-NoDerivs» 3.0 Unported. Программный текст примеров доступен по лицензии Unlicense (если иное явно не указано в заголовках файлов). Это произведение написано исключительно в образовательных целях и никаким образом не аффилировано с текущим или предыдущими работодателями автора.



    О чем писать дальше?


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 199 человек. Воздержалось 35 человек. Источник: habrahabr.ru,
    получено с помощью rss-farm.ru




    Прочитал, пищи еще!



    Прочитал, давай про компоновщик



    Прочитал, хочу детальнее про ассемблерный листинг на выходе



    Пролистал, если будет продолжение – тоже пролистаю



    Не читал, но голосовать люблю

    [Перевод] Это ваша вина… Смиритесь с этим

    TL:DR: Удалил все облачные , которыми пользовался, и взял данные обратно под контроль.

    Я их не порицаю. Просто все еще думаю о будущей сцене из фильма о Джеймсе Бонде.

    М: Видите ли, 007, нам нужно выяснить, кто из миллионов граждан нашей страны украл «Космический Лазер».
    007: Это может быть непросто, но я уверен, что с помощью невидимого автомобиля, часов, стреляющих отравленными дротиками, и парочки полуобнаженных русских агенток, мы сможем найти виновника.
    М: Ну, как вариант. Но, думаю, мы могли бы просто посмотреть на Букфейсе.
    007: Что?
    М: Букфейс, разве вы о нем не слышали? Ну вы и динозавр, 007. Несколько лет назад, для выяснения, чем занимаются жители страны, требовалось проведение всяких секретных операций под прикрытием. Теперь же можно просто заглянуть в Букфейс.
    007: То есть, они рассказывают свои секреты? Идиоты.
    М: Я знаю. Похоже, что среднестатистические граждане просто счастливы делиться каждым аспектом свой жизни, всей своей персональной информацией, каждым мнением, поступком и желанием. В обмен на возможность сказать своми друзьям и семье, что они только что покакали, или показать им милую фоточку котенка с забавной подписью внизу.
    007: Так вы утверждаете, М, что я вам больше не нужен?
    М: Нет, 007, не нужны. Я только что подключился к серверам Букфейса и запустил поиск всех людей, которые обновили свой статус и написали там «Украл гиганский Космический Лазер… lol, #WMD».

    Я виноват также, как и все остальные. Общаюсь с семьей в Фейсбуке, с друзьями в Google+, с коллегами в Твиттере. Держу документы в Dropbox, заметки в Evernote и фотографии в Picasa. Мои контакты в iCloud, календарь в Gmail, задачи в Wunderlist, пароли храню в Lastpass. Я даже позволил Apple отслеживать мои передвижения, на случай, если потеряю свой iPad, и Google меня отслеживает, когда мне нужно узнать, где найти ближайший МакДональдс.

    Я подписался на мириады сервисов, все они вроде-как «бесплатные», но в действительности — я приобрел услуги, расплатившись персональными данными. Можно возмущаться, что эти данные доступны (каким-либо методом) для АНБ в Штатах, и для GCHQ в Объединенном Королевстве, но нужно спросить себя — кто здесь действительно виноват? Предоставляя наши данные корпорациям (которые подчиняются законам стран, в которых работают), мы представили слишком доступные возможности секретным службам. Это как девственный лист пупырчатого полиэтилена, они же просто не могут сдержаться. Они вынуждены начать давить эти пупырышки приватности.

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

    Я не собираюсь завязывать потихоньку. Буду действовать в стиле Большого Взрыва. Избавлюсь от всех моих онлайн акаунтов на этих выходных.

    1. Facebook — как два пальца. Там у меня нет ничего ценного, так что удаление учетной записи не проблема. И я имею в виду именно удаление, а не деактивацию. Я уже делал эту ошибку раньше, при этом слишком заманчиво вернуться обратно. Всего лишь посмотреть, кто покакал или запостил картинку с котенком, который выглядит так, будто какает.

    2. Dropbox — сложнее. Я годами бережно лелеял 20Gb бесплатного пространства на Dropbox-е, и будет печально с ними расставаться. Тем не менее, обещание сделано, так что это должно случиться. Первым делом нужно найти альтернативу. BitTorrent Sync, похоже, пока с этим справится. Установил его на мой MacBook и MacMini и перенес свои файлы в свежесозданную директорию BTSync. Потом залогинился в Dropbox через веб-интерфейс, и удалил акаунт.

    Грустный вхлам Dropbox

    3. Браузер — я использую Chrome, и обычно залогинен в Google. Установил Firefox и отправил Chrome в Корзину.

    4. Поиск — больше никакого Google. Это достаточно просто. Удалил стандартные поисковые сервисы из Firefox-а и установил поиск со странным названием Duck Duck Go. Также изменил настройки приватности: всегда в режиме анонимного просмотра и не принимаю куки.

    5. Плагины браузера — чтобы чуть улучшить приватность, установил AdBlock Plus и NoScript.

    6. Интернет — знаю, что я не илитный хакер, но почти уверен, что если мне нужна приватность онлайн — значит придется иногда прятать IP. Как-то раньше игрался с Tor, но он слишком медленный. Также я не собираюсь пользоваться SilkRoad, т.к. мой наркотик продается в упаковках по 4 штуки в супермаркетах. Выбрал VPN. BTGuard, вроде-бы, достаточно уважаемый провайдер, я заплатил за три месяца вперед и настроил Mac.

    7. Microsoft — с этим всё просто. Skype или Windows не использую, и мой акаунт XBox больше ни с чем не связан. Жаль только, что как один из первых пользователей Outlook.com, я потеряю пару крутых адресов email. Однако, при попытке закрыть акаунт, от говорит, что мне нужно отменить платные подписки (которых у меня нет), и поскольку отменять нечего, я заперт в порочном круге. После милой беседы с «Агентом» Microsoft, мне сказали, что через 3 недели займутся этим и акаунт закроют.

    Переписка с «Агентом» Microsoft

    8. iCloud — легко. Сначала нужно перенести все документы iWorks из iCloud в папку BTSync. После этого я отключил синхронизацию с iCloud в календаре, заметках, контактах и просто держу их на моем Mac-е.

    9. LastPass — использвал этот менеджер паролей около года, и он мне нравится. Однако, для синхронизации паролей между устройстами, он хранит их в облаке. 1Password похож на разумною альтернативу, так что я раскошелился на 17 фунтов мелочью и установил его. Перенос паролей — через обычный экспорт/импорт CSV.

    Грустный LastPass

    10. Телефон — здесь всё хитро. Начнем с моего аппарата. Это Nexus 4, так что он сильно завязан на сервисы Google. К счастью, поскольку это Nexus, есть альтернативы. Выбрал Ubuntu Touch. Сейчас ОС далека от готовности, но с тех пор, как я получил возможность звонить, получать/отправлять SMS и использовать браузер — можно подождать, пока ОС обрастает возможностями. Выполнение инструкций с веб-сайта Ubuntu было достаточно простым, т.к. на телефоне уже был root. У меня случился небольшой сердечный приступ, когда телефон ушел в бесконечную перезагрузку, но вайп и установка в ручном режиме решила проблему и у меня теперь прикольная новая игрушка.

    UbuntuTouch@Nexus 4

    11. Google — мой основной (не рабочий) почтовый был адрес на Gmail-е. Также использовался G+ для фотографий и для связи с людьми. Я решил, что будет разумно воспользоваться Google Takeout для экспорта всех данных. У меня не самый быстрый интернет, так что нужно несколько часов, чтобы скачать 20Gb данных, которые лежали на серверах Google.

    Google Takeout

    У меня есть почта на школьном домене, которая теперь будет моим единственным персональным адресом электронной почты. О смене адреса никому не говорил, только убедился, что новый адрес используется всем моими акаунтами. Если кому-то нужно со мной связаться — они могут мне позвонить (если мой телефон на Ubuntu таки работает). Скачал GPG для Mac Mail и установил его для дополнительной безопасности, когда она понадобится.

    Осталось еще кое-что подчистить. Удалил остальные акаунты, такие как Evernote и Wunderlist, решил в дальнейшем использовать для этого SublimeText.

    Как-то так. Я свободен. Мои данные теперь мои. Осталось еще несколько вещей, с которыми предстоит разобраться. Хотелось бы иметь доступ к безопасной социальной сети — возможно, построенной на технологии P2P с межконцевым шифрованием, отложил это на будущее. Пока продолжаю использовать Twitter, поскольку он и так весь публичный, без претензий на приватность.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [recovery mode] Опыт эксплуатации Highscreen Black Box Outdoor в качестве экстрим-камеры

    Как я уже рассказывал в этом (http://habrahabr.ru/company/smartgadget/blog/189416/) посте, я являюсь счастливым обладателем спортивной фотокамеры Kodak EasyShare C123 Sport. Модель меня, в принципе, всем устраивает, но, тем не менее, периодически желание сменить ее на что-то другое возникает. Во-первых, в ней нет оптического зума. Во-вторых, это только «ручная» камера и ничего более – с ее помощью можно фотографировать с руки, а вот надежно закрепить данный аппарат на каком-нибудь наземном, наводном или подводном средстве передвижения практически нереально. И вот мне на тест достался Highscreen Black Box Outdoor – указанная модель является гибридом спортивной камеры и автомобильного видеорегистратора. Использовал ее несколько недель, по итогам которых и родился этот пост.


    Highscreen Black Box Outdoor с Kodak EasyShare C123 Sport



    Highscreen Black Box Outdoor поставляется в такой упаковке



    Комплектация Highscreen Black Box Outdoor

    В комплект поставки регистратора/экстрим-камеры входят:
    1. Съемный модуль с экраном.
    2. Обойма для креплений.
    3. Автомобильный держатель.
    4. Держатель на руль велосипеда или мотоцикла.
    5. Держатель для плоской поверхности на основе скотча 3M (плюс запасная наклейка со скотчем).
    6. Держатель на шлем.
    7. Пульт дистанционного управления.
    8. Автомобильное зарядное устройство.
    9. Герметичная заглушка для разъемов.
    10. Негерметичная заглушка для разъемов.
    11. Кабель питания.
    12. Кабель для подключения по USB.
    13. Кабель AV.
    14. Прорезиненный мешочек для переноски.
    15. Шнурок для ношения на шее.
    16. Краткое руководство пользователя.
    17. Гарантийный талон.


    Highscreen Black Box Outdoor на велошлеме


    Highscreen Black Box Outdoor на руле велосипеда

    Для начала – немного о характеристиках. Highscreen Black Box Outdoor может записывать видео в Full HD 1080p с частотой до 30 кадров в секунду. Также этот аппарат умеет фотографировать: максимальное разрешение снимков достигает 12 Мп, хотя камера на самом деле имеет разрешение 5 Мп. Следовательно, если выставить в настройках разрешение более 5 Мп, то будет использоваться интерполяция. В случае видео она в Highscreen Black Box Outdoor не применяется – эта «фишка» со знаком минус, имевшая место во многих бюджетных регистраторах, сегодня плавно уходит в прошлое (и слава богу).

    Внешне Highscreen Black Box Outdoor представляет собой цилиндр, на одном конце которого находится объектив, а на другой – панелька с портами MiniUSB, HDMI, двумя микрофонами, слотом для памяти microSD (до 32 Гб, 64 не работает, проверял) и переключателем разрешения видео (720p/1080p).



    Также здесь есть резьба, на которую накручивается одна из трех комплектных насадок. Две из них представляют собой пластиковые колпачки – с отверстиями и без. Первый можно задействовать, например, при съемке с руля велосипеда, второй – для подводной съемки (так как он герметичный). Третья насадка – так называемый экранный модуль. На нем есть собственно небольшой дисплей с диагональю 1,5 дюйма, клавиши для управления и настройки, а также еще один порт MicroUSB. То есть Highscreen Black Box Outdoor можно заряжать и сам по себе, и с присоединенным экранным модулем. Кстати, с последним этот регистратор/экстрим-камера напоминает маленькую зеркалку с телеобъективом.




    Заглушка первая, «подводная»


    Заглушка вторая, с перфорацией


    Highscreen Black Box Outdoor с подключенным экранным модулем

    Корпус отделан пластиком типа «софт-тач» и очень аккуратно собран (что особенно актуально именно для «подводных» гаджетов, так как любая микроскопичная щель может привести к поломке).

    Любопытно, что в комплект поставки Highscreen Black Box Outdoor входит шнурок, однако я далеко не сразу понял, как он крепится. В итоге съехал с горки в аквапарке, аппарат вылетел у меня из руки, и потом мы дружно, толпой в пять человек, искали его на дне бассейна. Позже до меня дошло, что шнурок крепится следующим образом: перед закручиванием любого из двух колпачков его нужно как бы надеть на регистратор, а потом придавить этой самой заглушкой. Держится шнурок вполне надежно.



    Положа руку на сердце, скажу, что особого смысла в модуле с дисплеем лично я для себя не нашел. Да, он позволяет просматривать отснятое видео и фото, но я для этих целей задействовал Samsung Galaxy S4. То есть из Highscreen Black Box Outdoor извлекалась карточка, вставлялась в смартфон и так далее по списку. Именно так я всегда поступаю и с Kodak EasyShare C123 Sport: в нем даже более крупный дисплей, однако рассматривать контент все равно не очень удобно. Между тем во время направления объектива на дорогу или какой-либо другой объект без экрана тоже можно обойтись: в Highscreen Black Box Outdoor предусмотрен лазерный уровень – то есть красный луч, как в небезызвестных указках.

    Однако без экранного модуля Highscreen Black Box Outdoor может только писать видео – для этого на его корпусе предусмотрена специальная клавиша (к слову, достаточно тугая). Для фотографирования нужно или подсоединить экран, или воспользоваться комплектным пультом дистанционного управления. Именно здесь скрывается весьма серьезный лично для меня недостаток устройства: в отличие от самого Outdoor'а, пульт не защищен от воды, так что в море его с собой не возьмешь. Экранный модуль – тем более. А раз так, то под водой с помощью Highscreen Black Box Outdoor можно только писать видео. Я же люблю скорее фотографировать рыбок и морских ежей, а на снимать фильмы об их нелегкой жизни.



    С другой стороны, с видео Highscreen Black Box Outdoor справляется очень неплохо – куда лучше «Кодака». И это касается не только разрешения (Full HD против VGA), но и его качества. Вот пара примеров (настоятельно рекомендую смотреть на сайте YouTube, выставив перед этим разрешение Full HD 1080p):



    Цилиндрическая форма устройства, на мой взгляд, тоже является спорным моментом. Да, благодаря ней Highscreen Black Box Outdoor получился весьма компактным (диаметр около 30 мм, длина – 80). Однако, в то же время, из-за цилиндрической формы его не всегда получается зафиксировать в руке в положении «кнопкой вверх» – именно в нем горизонт не заваливается и получаются нормальные ролики. Если же взять его в руку неправильно, то он будет терять сигнал сети – антеннагейт, блин видео будет «косым». Со временем, конечно, приучаешься держать Black Box Outdoor как нужно, и все же такой нюанс есть.

    Протестировать устройство удалось не только в воде, но и в куда более экстремальных условиях. Есть у меня один знакомый, обожающий разного рода радиоуправляемые гаджеты. В настоящее время он владеет машинкой AMG Mercedes C-Class DTM 2008, собранной с помощью журнала De Agostini. То есть покупаешь номера, и в комплекте с каждым из них идет одна деталька. Покупаешь, собираешь, тратишь без малого тысячу долларов – и на выходе получаешь полноприводную машинку с лексановым кузовом, пружинной подвеской и бензиновым движком, которая может разгоняться до 80 километров в час.


    Пока хозяин готовит шасси…


    … мы закрепляем Highscreen Black Box Outdoor на лексановом корпусе


    Шасси рядом с корпусом


    Все вместе выглядит вот так

    Так вот он уже прикреплял к ней некий безымянный гибрид регистратора и экстрим-камеры, купленный на eBay примерно за 100 долларов. Все бы хорошо, но хлипкое крепление от бешеной тряски (ровного асфальта в России нет, не забывайте) развалилось на части, горе-регистратор улетел в сторону и со всей дури треснулся об асфальт. Поэтому Highscreen Black Box Outdoor мы цепляли к машинке с некоторой опаской – угробить следом за «китайцем» еще и эту штуку за 8 тысяч рублей не хотелось. К счастью, Outdoor и его держатель на основе скотча 3М это испытание выдержали без каких-либо проблем.

    На выходе получилось вот такое видео (повторюсь: асфальт не слишком ровный, подвеска маленькая и жесткая, лексановый корпус шатает из стороны в сторону, скорость до 80 км/ч):


    А вот как все это выглядело со стороны:


    На всякий случай приведу пару примеров автомобильного видео – дневного и ночного.



    Благодаря своей компактности Highscreen Black Box Outdoor вполне можно расположить за зеркалом заднего вида, причем как с отсоединенным экранным модулем, так и с ним. Запись стартует автоматически при включении двигателя. В автономном режиме аппарат работает до полутора часов.


    Highscreen Black Box Outdoor в машине

    В целом – устройство интересное. Не без недостатков, конечно, но достоинств больше. Себе в коллекцию я его захотел (и, наверное, таки куплю), но «подводную» фотокамеру оно заменить, увы, не в состоянии. Просто потому, что фоткать под водой Highscreen Black Box Outdoor не умеет. Если же вас интересует возможность снимать видео на глубине до 5 метров – тогда да, вариант неплохой. Тем более что на пути с морского курорта его можно задействовать в автомобиле в качестве видеорегистратора.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Автоматизированный расчет параметров частиц по фото

    Привет!

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

    О том, как мы искали свой алгоритм, рассказываем на примере керамзита.

    Характеристики частиц почвы определяются с помощью эмпирического метода Krumbein & Sloss, основным инструментом при работе с которым является следующая классическая таблица:


    Фото частиц, или непосредственно сами частицы распределяются по ячейкам таблицы и затем считаются средние значение сферичности и окатанности (Sphericity & Roundness).

    Перед нашими разработчиками встала задача автоматизации процесса подсчета этих характеристик.

    Этапы работы


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

    2. Построение бинарной маски
    Для оценки формы по таблице Krumbein & Sloss используются четкие контуры объектов.

    Задача — их получить.

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


    Рис 1. Исходное изображение

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

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


    Рис 2. Бинарная маска с применением морфологических операций

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

    Казалось бы, тут нам на помощью пришел бы анализ площади белых областей, мелкие — залить, крупные участки белого фона — оставить. Но не тут-то было. Некоторые частицы лежали близко друг к другу группами по 3. Если избавимся от всех бликов, то исчезнут и ключевые области между частицами (на Рис 2 обведено красным).

    Размер областей одинаковый, применить фильтр не вышло. И тут нас осенило: король-то голый частицы-то непрозрачные! А значит можно немного усложнить жизнь пользователю, поставив условие применить цветной фон при съемке, но при этом решить задачу построения маски с гораздо большей точностью. Так и сделали. Вместо градаций серого взяли разницу между красной и зеленой компонентами.



    Рис 4.1. Изображение в градациях серого
    Рис 4.2. Бинарная маска, построенная по градациям серого



    Рис 5.1 Разница компонент Red-Green
    Рис 5.2 Бинарная маска, построенная по разнице компонент Red-Green
    Как видно, бинарные маски, полученные с помощью метода Отсу, различаются точностью в тех областях, где падает тень от объектов. Если немного изменить порог бинаризации вручную, то результат будет одинаковым. Но плюс и одновременно минус метода Отсу для разделения изображения на два класса состоит в том, что порог бинаризации определяется автоматически. А так как нужно было определять порог разделения без участия пользователя, то был выбран именно этот метод.

    3. Как разделить частицы
    Как видно на снимке, далеко не все частицы лежат отдельно, здесь нам на помощь приходит метод водораздела (watershed).
    Мы использовали Marker-controlled watershed segmentation, базируясь на этом описании http://www.mathworks.com/products/image/examples.html?file=/products/demos/shipping/images/ipexwatershed.html.

    Строим евклидово расстояние по бинарной маске.


    Рис 6. Euclidean distance
    Дополняем маркерами


    Рис 6.1. Евклидово расстояние, совмещенное с маркерами

    Применяем к изображению с маркерами метод водораздела.


    Рис 7. Области «водораздела»

    4. Характеристики
    Формулы для характеристики частиц были подсмотрены в этой статье: Particle Shape Determination by Two-Dimensional Image Analysis in Geotechnical Engineering. Rodriguez, J.M. Johansson, J.M.A. Edeska?r, T.

    http://pure.ltu.se/portal/files/36945408/Rodriguez_Johansson_Edeskar_Particle_Shape_Determination_by_Two_Dimensional_Image_Analysis_in_Geotechnical_Engineering.pdf

    Перебрав все формулы, решили остановиться на этом:



    качества
    6. Ключевым порогом качества в оценке формы частиц считается значение 0.8.
    Те частицы, значение параметра R (roundness) или S (sphericity) ниже заданного порога, помечаются на снимке красными лейблами.


    Рис 8. Результат вычисления

    7. OpenCV
    Прототип готов, но чтобы получить реальное приложение, доступное пользователям через веб, надо перейти от алгоритмического прототипа к его воплощению в коде. Для того чтобы реализовать эти алгоритмы на сервере, мы выбрали OpenCV. Обычно мы не сталкивались с проблемами реализации алгоритмов обработки изображений с помощью этой библиотеки. Но здесь столкнулись со следующим нюансом: алгоритм водораздела, реализованный в OpenCV, даёт значительные искажения вдоль границ разделения частиц.



    Такие искажения вносят существенную ошибку в определение параметров сферичности и окатанности. Таким образом, такая реализация алгоритма разделения нам не подошла.


    Рис 9. Наша альтернатива watershed

    В итоге мы отдали предпочтение более простому алгоритму.

    Суть использованного нами алгоритма:

    1. Находим центр масс маркера. Положение маркера соответствует внутренней области соответствующей частицы. То же справедливо и для центра масс маркера.
    2. Движемся вдоль прямой, параллельной оси x и проходящей через центр масс маркера, до точки, имеющей цвет фона: получаем расстояние R от центра масс маркера до границы частицы или их скопления.
    3. Последовательно изменяя угол наклона прямой? от 0 до 2pi, получим функцию зависимости расстояния от угла R(?). Скачки данной функции – это потенциальные точки разделения.
    4. Следующий шаг – найти пороги, определяющие то, какие пиксели считать точками разделения. Первый порог определяет величину скачка функции, второй – максимальное расстояние, на котором скачок функции может считаться точкой разделения. Величины этих порогов зависят от взаимного расположения маркеров разных частиц и для каждого маркера будут свои.


    Возможный случай разделения

    5. При правильно рассчитанных пороговых значениях скачка функции R(? ) количество точек разделения будет четным. Знак первого обнаруженного скачка определяет порядок соединения точек разделения.

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

    В ходе поиска решения были проведены поиски на просторах интернета и найдены интересные по данной теме:
    stackoverflow.com/questions/11294859/how-to-define-the-markers-for-watershed-in-opencv
    luispedro.org/projects/nuclear-segmentation

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Постраничная выборка данных — альтернативный взгляд на давно известное

    Проблема постраничной выборки информации из БД стара, как сама БД, и соответственно, обсуждена не одну тысячу раз. Нет, пожалуй, ни одной клиент-серверной системы, в которой эта проблема так или иначе не была бы адресована и решена. Сегодня я хочу рассказать об одном немного нестандартном способе взаимодействия клиентского слоя и MS SQL-бакенда при организации постраничной выборки в типичном публичном веб-приложении.

    Для начала очертим типичные бизнес-требования и выведем из них входные условия — мы выбираем данные из некоторого списка (пользователей, товаров, транзакций) страницами по N записей на каждой, начиная с M-ной. Выборка осуществляется с примемением одного или более фильтров и некоторого критерия сортировки. Проблемы чисто клиентских решений типа интерактивных гридов на джаваскрипте, в которые нужно загрузить все данные, здесь рассматривать не будем, а остановимся на более умеренных вариантах, в которых постраничная выдача делается на сервере.

    Как это делается традиционно? Слой приложения передает в бакенд значения фильтров, индекс первой нужной записи, и требуемое количество записей на страницу. В ответ база данных, прикладывая фильтры ко всей выборке, упорядочивает весь фильтрованный поднабор, и отдает назад записи с M до M+N-1. То, каким конкретно образом это сделает тот или иной разработчик и/или та или иная версия RDBMS, сейчас для нас несущественно — важно лишь что, что какой бы способ не использовался (временная таблица в MS SQL 2000, ROW_NUMBER OVER () в 2005-2008, или TOP / OFFSET в 2011), необходимость выдачи нумерованного подмножества из фильтрованного упорядоченного множества обязательно означает раскручивание всего промежуточного результата после фильтра и его сортировку. Несущественно также и то, где будет произведено это раскручивание — непосредственно на пространстве данных, или на поле индексов (например, при использовании полного индексного покрытия или INCLUDED-колонок) — принципа эта разница не меняет.

    Понятно, что если коэффициент фильтрации невысок, а фильтр — трудоемкий (например, полнотекстовый поиск), то КПД подобного метода будет очень низок, особенно по мере приближения к последним страницам выборки. И даже если фильтр — параметрический (например, по типу пользователя в таблице пользователей), и работает по специально созданному индексу, выкидывание в помойку почти 100% усилий сервера для каждого запроса последних страниц вызывает искреннюю жалость к железке, на которой сам RDBMS, собственно, и крутится.

    В реальных же клиент-серверных приложениях существуют еще несколько моментов, усложняющих ситуацию:

    a) чтобы правильно отрендерить страницу с пагинацией (прошу прощения за термин), слой приложения должен знать общее количество записей, проходящих через фильтр — для того, чтобы разделив его на N и округлив вверх (с очевидной оговоркой), получить количество страниц, нужное для меню навигации. Чтобы этого достичь, бакенд должен фактически либо выполнять при выборке каждой страницы поисковый запрос дважды — первый раз в усеченном варианте — выбирая просто… COUNT (1)… WHERE, без частичной выборки и сортировки, а второй — уже в полном, с выборкой нужного набора записей. Либо выполнять COUNT при первом переходе к фильтрованному выводу, и запоминать это значение.

    б) если за время навигации пользователя по страницам в базе появится новая (или удалится существующая) запись, попадающая под условие фильтра — навигация съедет, и юзер имеет все шансы либо пропустить, либо повторно просмотреть одну или более записей.

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

    Типичный алгоритм операций при постраничной навигации выглядит на си-подобном коде так (функции с префиксом DB выполняются в базе данных):
    <code>while (1) 
    {
      create_filter(FormData, &F, &S);  // создаем фильтр F и дефолтный критерий сортировки S 
                                                                 // из параметров поиска на форме FormData
    
      DB_get_count(F, &C);                  // запрашиваем фильтрованное кол-во записей для построения меню навигации
    
      while (1)                                          // навигируемся, пока F и S неизменны (иначе начинаем сначала)
      {
     
       DB_get_records(F, N, M, S);      // выбираем N записей, начиная с M по фильтру F и сортировке S
    
       if (SORT_OR_FILTER_CHANGED  ==   do_navigation(FormData, C, &N, &M, &S))   // обрабатываем пользовательскую навигацию
       {
                break;                                   // если сортировка или фильтр поменялись - все сначала
       }
    
      }
    }
    </code>

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

    По аналогии с функцией DB_get_count псевдокода назовем ее DB_get_keys

    Вторым шагом будет переписывание функции выборки данных с N по N+M-1 по заданным фильтрам и сортировке на функцию, которая выберет N записей с ключами, соответствующими переданному ей массиву ключей строго в порядке их нахождения в массиве. Сигнатура ее пусть будет
    <code>DB_get_records_by_keys(*K, N)</code>
    , где K — адрес массива ключей с нужной точки (то есть с M, а N — количество записей, которое нужно выбрать по этим ключам. Наш псевдоалгоритм теперь будет выглядеть так:

    <code>while (1) 
    {
      create_filter(FormData, &F, &S);  // создаем фильтр F и дефолтный критерий сортировки S 
                                                                 // из параметров поиска на форме FormData
    
      DB_get_keys(F, S, K);                  // заполняем массив ключей K по фильтру F и сортировке S
      while (1)                                          // навигируемся, пока F и S неизменны (иначе начинаем сначала)
      {
     
       DB_get_records_by_keys(&(K[M]), N);      // выбираем N записей, начиная с M
    
       if (SORT_OR_FILTER_CHANGED  ==   do_navigation(FormData, C, &N, &M, &S))   // обрабатываем пользовательскую навигацию
       {
                break;                                   // если сортировка или фильтр поменялись - все сначала
       }
    
      }
    }
    </code>

    Теперь попытаемся дать качественную оценку скорости его выполнения относительно классического. Примем допущение, что время передачи выбранного массива ключей от бакенда ничтожно мало по сравнению с временем поиска нужных данных (так это обычно и есть при передаче небольшого их количества и хорошем сетевом интерфейсе между сервером БД и серверами приложения). Так как общий алгоритм работы остается неизменным, нам достаточно только сопоставить разницу между функциями БД DB_get_count ?? DB_get_keys и DB_get_records ?? DB_get_records_by_keys.

    Скорее всего, DB_get_count будет работать немного быстрее, в основном из-за того, что подсчет выбранных фильтром строк (то есть подсчет первичных ключей строк) не потребует внутренней сортировки, плюс отсутствие необходимости выдавать эти ключи из SQL engine наружу. Для сравнения — два execution plan'а:image

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

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

    С точки зрения реализации всей идеи БД, остается лишь один момент — как эффективно передать [под]массив ключей в качестве параметра в статемент или процедуру так, чтобы результирующий вывод сохранил порядок ключей в массиве?

    Разобъем эту задачу на две — передача массива в качестве параметра в код БД и собственно, сохранение порядка. Решений первой задачи несколько — основанных на XML или CSV-представлении, либо создании и заполнении табличной переменной. Сам же SQL-код, преобразовывающий входной массив в набор строк может быть выполнен как динамический SQL-запрос, процедура, или табличная функция.

    Наиболее гибкой оказывается версия, выполненная без динамики как table function (TF) с использованием CTE — так называемых Common Table Expressions, позволяющих в MS SQL 2008 строить рекурсивные запросы для обработки вложенных данных.
    Эту возможность CTE, наряду с возможностью TF быть использованной в качестве table source в составных запросах, мы и используем.

    Задачу же сохранения порядка сортировки решим добавлением в структуру возвращаемой TF таблицы поля identity с нужным значением seed и increment (чтобы можно было сортировать снаружи), и указанием явного порядка вставки записей в возвращаемую таблицу (внутри). Функция в итоге получилась такая:

    <code class="sql">CREATE FUNCTION [dbo].[TF_IDListToTableWithOrder] (
    	@ListString	varchar(MAX),
    	@Delim char(1)
    ) RETURNS @ID TABLE
    		(
    		RowIdx INT IDENTITY(0, 1) PRIMARY KEY CLUSTERED, -- поле для внешней сортировки
    		ID INT				 -- здесь храним значения ключей
    		)
    AS 
    BEGIN
    
    	SET @ListString = REPLACE(@ListString, ' ', '')
    	IF LTRIM(RTRIM(ISNULL(@ListString, ''))) = '' 
    		RETURN			-- список пуст, выходим с пустой таблицей
    		
    	SET @ListString = @ListString + @Delim	-- добавляем хвостовой разделитель, чтобы CHARINDEX всегда давал > 0, включая последний ключ
    
    	;				-- CTE требует этого разделителя
    	
    	WITH IDRows (ID, Pos) AS
    	(
    		-- якорная часть (первый ключ)
    		SELECT CONVERT(INT, SUBSTRING(@ListString, 1, CHARINDEX(@Delim, @ListString, 1) - 1)), CHARINDEX(@Delim, @ListString, 1) + 1
    
    		UNION ALL
    
    		-- рекурсивная часть (следующий ключ с позицией, большей последней найденной)
    		SELECT CONVERT(INT, SUBSTRING(@ListString, Pos, CHARINDEX(@Delim, @ListString, Pos) - Pos)), CHARINDEX(@Delim, @ListString, Pos) + 1
    		FROM IDRows
    		WHERE Pos < LEN(@ListString)	-- условие окончания рекурсии
    	)
    
    	-- переписываем все CTE в возвращаемую таблицу
    	INSERT INTO	@ID (ID)
    	SELECT ID
    	FROM IDRows ORDER BY Pos	-- упорядоченную по позиции разделителя - т.е. по позиции ключа во входном массиве
    	OPTION (MAXRECURSION 32767) -- глубина рекурсии по умолчанию 100 (может не хватить, поэтому ставим макс возможную)
    	RETURN
    END</code>

    Проиллюстрируем использование на примере.

    Создаем таблицу с тестовыми данными и убеждаемся, что они достаточно разнообразны ;):
    <code class="sql">
    DECLARE @testdata TABLE (ID INT IDENTITY PRIMARY KEY CLUSTERED, Name VARCHAR(128))
    INSERT INTO @testdata
    SELECT TOP 1000 A.name + B.name
    FROM sysobjects A
    CROSS JOIN sysobjects B
    ORDER BY NEWID()
    
    SELECT * FROM @testdata
    </code>

    Имитируем выборку ключей нашей функцией DB_get_keys с обратной сортировкой по искомому полю и сразу конвертим ее в CSV:
    <code class="sql">
    DECLARE @STR VARCHAR(MAX) = ''
    SELECT TOP 20 @STR = @STR + ',' + CONVERT(VARCHAR, ID) FROM @testdata WHERE Name LIKE 'C%' ORDER BY Name DESC
    IF LEN(@STR) > 0
       SET @STR = RIGHT(@STR, LEN(@STR)-1)
    
    SELECT @STR
    </code>

    И наконец, имитируем DB_get_records_by_keys:
    <code class="sql">
    SELECT TD.*
    FROM @testdata TD
    INNER JOIN dbo.TF_IDListToTableWithOrder(@STR, ',') LTT ON TD.ID = LTT.ID
    ORDER BY LTT.RowIdx
    </code>

    Чтобы заставить все это работать в связке с сервером приложения, нужно сохранять в пользовательском контексте (для веба — в сессии) массив значений ключей на время навигации, что казалось бы, потребует большого объема памяти. Однако, если ключи целочисленные, и хранятся в простом скалярном массиве, а не в массиве объектов (разница принципиальная!), то скажем 100 000 ключей займет на сервере приложения всего 400 кБайт, что по современным меркам совсем немного.

    Теперь про чувствительность метода к добавленным/удаленным во время навигации записям. Понятно, что вновь добавленные записи, попадающие под критерий фильтра пользователь не увидит — т.к. значения их ключей появятся позже момента выборки всего списка. Что же касается удаления, то, естественно, отсутствующая запись не будет возвращена, и количество фактически полученных записей по набору ключей может оказаться меньше затребованного. Эту ситуацию можно обработать на слое приложения, сравнив ID полученных записей с запрошенными, и выведя на месте отсутствующих какую-нибудь заглушку типа «Просматриваемая запись была удалена», чтобы не нарушать layout из-за изменения общего количества. А можно и сделать LEFT JOIN результата табличной функции с бизнес-таблицей — в таком случае для удаленной записи все поля будут NULL — и уже этот факт обработать на клиенте. В общем, варианты имеются.

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    πfs — революционная файловая система без хранения данных­

    Что это?

    ?fs это революционная файловая система, которая вместо того, чтобы тратить место на вашем жестком диске, хранит все данные в?.. Вам никогда больше не придется заботится о свободном месте! Вам говорили, что 100% сжатие невозможно? Да вот же оно!

    Как собрать?

    ?fs собирается элементарно:
    <code>./configure
    make</code>

    Да и использовать его не сложнее:
    <code>?fs -o mdd=<metadata directory> <mountpoint>
    </code>
    Где metadata directory — каталог с метаданными (названия файлов, смещение в ?), а mountpoint ­— каталог монтирования.

    Что же? делает с моими данными?

    ? — одна из самых важных констант математики, и у нее есть куча интересных свойств (о которых можно прочесть в статье на википедии)
    Одним из таких свойств числа? предположительно является нормальность, что означает, что все его числа распределяются равномерно, при условии, что это дизъюнктивная последовательность, т.е. все конечные числовые последовательности находятся внутри него. Если мы рассмотрим число? по основанию 16 (HEX), то это предположение верно. Первая запись об этом была в 2001 году.
    Ну а если так, то зачем нам хранить все эти эксабайты данных на винчестерах, если мы можем найти их в ??

    И что, прямо каждый-каждый файл можно найти в ??
    А ТО! Любой файл, который создали вы или кто-то другой, или даже еще не создали! Вас судят за нарушение копирайта? Да хрена с два — вы просто достали последовательность из константы, она всю жизнь там была!

    Но как же найти мне свои данные в ??
    Если вы знаете смещение файла и его длину в ?, вы можете их достать используя формулу Bailey–Borwein–Plouffe. Аналогично, вы можете использовать эту формулу чтобы узнать смещение вашего файла.
    Так как нахождение целиком нужной последовательности займет слишком много времени, нам нужно разбить файл на несколько маленьких последовательностей для увеличения быстродействия.
    В этой реализации, мы разбиваем файл на отдельные байты, и эти байты ищем в?..

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

    Ну а если я потеряю смещение?
    Да ничего страшного — ваши данные от этого из? не пропадут! Найдете когда-нибудь.

    Почему это говно такое медленное? На сохранение 400 строк теста у меня ушло 5 минут!
    Ну, это прототип, к тому же, у нас есть закон Мура!

    Исходник на GitHub

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Последствия падения «челябинского метеорита»: видео-модель от NASA



    При падении крупного (или даже не очень) космического тела на Землю образуется не только кратер (в случае, если метеорит таки ударился о поверхность). Падение крупного метеорита, да и его падение, влечет за собой появление в атмосфере планеты пылевого облака, которое может «висеть» много недель. Все сказанное актуально и для метеорита, упавшего на Челябинск. Специалисты из NASA смоделировали движение пылевого облака, образовавшегося вследствие падения этого космического тела, и выложили видео-модель на YouTube.

    Как известно, мощность взрыва «челябинского метеорита» превосходит примерно в 30 раз (в комментариях говорят, в 21 раз) мощность взрыва атомной бомбы, сброшенной на Хиросиму. Само собой, облако пыли от такого взрыва тоже очень велико. По словам специалистов NASA, это облако распространялось по всему северному полушарию в течение четырех дней, а затем осталось в атмосфере на несколько месяцев (около трех).


    Спутник Suomi-NPP смог оценить размер облака, а также помочь ученым отследить изменения размеров этого облака и его скорость. Так, в течение примерно трех часов после падения метеорита облако распространялось со скоростью примерно 300 километров в час.

    И да, масса метеорита, а не отдельных его осколков, составляла 11 тысяч тонн.

    Via nasa

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Пакет игр, книг и фильмов по произведениям Лавкрафта

    Все поклонники творчества Говарда Филлипса Лавкрафта и его примилейшего Ктулху могут добавить в свою коллекцию некоторые экспонаты за небольшой взнос (добровольная система пожертвований от $0.1 до $100):

    1) Игра Cthulhu Saves The World
    2) Фильм The Colour Out Of Space
    3) Аудиокнига Lovecraft Audio Drama Pack 1 (только на языке оригинала)
    4) Ну и Lovecraft eZine ебук для истинных фанатов

    Тем кто расщедрится более, чем на $2,51 в нагрузку обещают:

    1) Call of Cthulhu: The Wasted Land — игра, на Windows и Android
    2) Sherlock Holmes: The Awakened — тоже игра, но уже только на Windows
    3) Innsmouth Free Press — журнал фантастики
    4) Аудиокника Lovecraft Audio Drama Pack 2

    Акция ограничена, осталось около 3х дней! :)

    Получить это все можно на легальном трекере VoDo

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [recovery mode] Алгоритмизация правосудия

    Количество информации, доступной для обработки и анализа с помощью компьютеров, растёт, как снежный ком. Данные с камер видеонаблюдения, GPS-трекеров, сенсоров мобильных телефонов, записи финансовых транзакций, история посещений страниц в интернете оказывают всё большее влияние на принятие решений. И чем больше этих данных, тем больше приходится полагаться на их автоматическую интерпретацию. Неизбежное следствие этого — появление систем «компьютерного правосудия», которые без участия человека выявляют нарушения законов и правил. Штрафы за превышение скорости, выписываемые автоматически на основании данных с видеокамер и радаров или система анализа контента на Youtube, которая ищет нарушения копирайта — это уже повседневная реальность.

    Группа американских учёных, объединяющая юристов, лингвистов и программистов, провела интересный эксперимент в этой сфере. В ходе эксперимента 52 студента-программиста должны были составить программу, которая анализировала бы данные с GPS-трекера, установленного в автомобиле и выписывала штрафы за нарушение скоростного режима в соответствии с правилами дорожного движения штата Нью-Йорк. Это оказалось очень непростой задачей — даже в самых законопослушных государствах законы никогда не выполняются буквально и на все 100%. Часть нарушений остаются незамеченными, часть слишком незначительна, чтобы правоохранители обратили на них внимание. Компьютеры же ничего не забывают и ничего не упускают. Бездумное применение правил и алгоритмов приводит к излишне жестким наказаниям и нелепым ошибкам вроде блокирования видео с шумом ветра за нарушение копирайта.

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



    По графику скорости автомобиля видно, что водитель в целом соблюдал — незначительные пики, выходящие за рамки официальных ограничений скорее всего были связаны с обгонами на трассе или изменением рельефа. При этом программы, следовавшие букве закона, за время поездки в среднем выписывали абсурдные 498 штрафов. В группе, следовавшей духу закона, в среднем нарушение регистрировалось 1,5 раза. Группа, писавшая код по составленной экспертами спецификации вообще не нашла нарушений.

    В ходе написания программ выявилось множество факторов, о которых в законе не сказано ни слова, но которые оказывают огромное воздействие на принятие решений. Какова погрешность датчика? Считается ли нарушением превышение скорости на 5 миль в час? А на 10? Если оно длилось всего несколько секунд? Или минут? Или повторялось несколько раз в течение часа? Эти и другие вопросы законодатель оставляет на усмотрение исполнителей. Живой полицейский вряд ли будет штрафовать водителя, превысившего скорость на несколько секунд во время обгона (по крайней мере, если он заинтересован реальном соблюдении правил, а не в выполнении плана по штрафам). У программы же нет здравого смысла, так что программисту необходимо учесть все нюансы и особые случаи.

    Интересно, что студенты из разных групп очень по-разному отнеслись к возможности того, что их программа будет анализировать их собственную езду. В группе, следовавшей букве закона, лишь один студент согласился с этим, но лишь при условии, что в системе будет «бэкдор», который позволит ему избежать наказания. Такими же низкими были результаты тех, кто писал программу по жестко заданной спецификации, и это несмотря на полное отсутствие штрафов в их версии программы. Лишь среди тех, кто сам решал, как должна работать программа, набралось 37,5% готовых подчиниться её решению.

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


    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Разгон Arduino. Под жидким азотом. 20 ⇒ 65.3Mhz @ -196 °C

    До начала статьи сразу следует ответить на 2 вопроса, к гадалке не ходи — они будут заданы:

    1) Какой в этом практический смысл? Разобраться в том, как ведет себя электроника при криогенных температурах, да и просто интересно сколько можно выжать из 20Мгц AVR-ки :-) Удалось выяснить момент, крайне важный и для разгона настольных процессоров с криогенным охлаждением.

    2) Почему Arduino, ведь есть же куча микроконтроллеров быстрее, а i7 вообще всех рвет? Совершенно верно. Есть куча намного более современных микроконтроллеров, которые на 2-3 порядка быстрее (и они есть у меня в наличии). Однако Arduino получила большую известность среди любителей, потому было решено мучить именно её. А для практических применений конечно дешевле и проще взять более быстрые микроконтроллеры (Cortex-M3, M4).

    Разгон микроконтроллера под жидким азотом обещает быть несколько сложнее разгона «настольных» процессоров — ведь тут нет ни тестов стабильности, ни программируемого генератора тактовой частоты, ни управления напряжением питания. Да и компоненты на Arduino, как показала практика, не выдерживают криогенных температур — и с ними придется разбираться в индивидуальном порядке. Все эти проблемы к счастью удалось решить.

    Жидкий азотДавно хотел до него дорваться. Оказалось, в Москве его продают несколько компаний. Ближе всего был НИИ КМ, там азот по 50 рублей за литр. Некоторые компании не морщась за 5 литров просят 950 рублей — с ними нам конечно не по пути.

    Жидкий азот получают буквально из воздуха — сжижая его и разделяя на ректификационной колонне, или наоборот — сначала выделяя азот из воздуха специальными фильтрами, и затем сжижая. Как оказалось, продаются даже небольшие установки по производству жидкого азота (10 литров в день). Себестоимость производства по электроэнергии — 5-10 рублей за литр. Теперь я точно знаю, что хочу себе на день рождения!



    Переносить азот можно в обычных стальных термосах (стеклянные могут треснуть от резкого падения температуры). После дополнительного утепления (+1 сантиметр теплоизоляции и полиэтилен для защиты от конденсата) азот выкипал за 30 часов, что в принципе достаточно для работы. Покупать специальный сосуд Дьюара — достаточно дорогое удовольствие, хотя азот из маленьких (~5 литров) «правильных» сосудов Дьюара выкипает уже за 25 дней. Также нужно помнить, что ни в коем случае нельзя герметично закрывать жидкий азот — разорвет в клочья.

    На physics.stackexchange.com/ подсказали, что термоизоляцию нужно делать наоборот — надевать сверху, а не снизу. Чтобы испаряющийся азот охлаждал внешнюю стенку термоса.


    Нагрузочное тестированиеПришлось написать тест, который тестирует чтение/запись в SRAM, чтение из flash, арифметические операции и program flow тест (с ветвлениями). Идея тестов — была найдена последовательность команд, которая выводит систему из начального состояния, и затем через определенное количество шагов — приводит в исходное. Скачать законченный стресс-тест можно тут.
    Смотреть тесты
    <code class="cpp">void run_flow_test()
    {
      for(int repeat=0;repeat<250;repeat++)//We are aiming at ~10 benches per second
      {
        //Program flow check
        //Magic loop which after 93 itterations yields same value
        for(unsigned char i=0;i<93;i++)
        {
          flow_check=(flow_check<<1) + (flow_check>>7) + 25;
          if(flow_check&8)
            flow_check^=4;
          else
            flow_check^=16;
          flow_check=flow_check ^ 192 + 1;
        }
      }
    }
    
    void run_mul_test()
    {
      for(int repeat=0;repeat<350;repeat++)//We are aiming at ~10 benches per second
      {
        //Multiplication check
        for(unsigned char i=0;i<64;i++)
        {
          mul_check=mul_check*(mul_check-1);
          mul_check=mul_check*(mul_check+1)+2;
        }
      }
    }
    
    void run_flash_test()
    {
      for(int repeat=0;repeat<1000;repeat++)//We are aiming at ~10 benches per second
      {
        //flash_check
        for(unsigned char i=0;i<16;i++)
        {
          flash_check=(flash_check ^ svalue1) + svalue2;
          flash_check=(flash_check<<((svalue3+flash_check)&7)) + (flash_check>>((svalue3+flash_check)&7)) + svalue4;
        }
      }
    }
    
    void run_sram_test()
    {
      for(int repeat=0;repeat<10;repeat++)//We are aiming at ~10 benches per second
      {
        //SRAM check
        for(int i=0;i<2405;i++)
        {
          value1=(value1+value2+value3+value4+sram_check)&1;
          value2=(value2+value1+value3+value4+sram_check)&1+1;
          value3=(value3+value1+value2+value4+sram_check)&1+2;
          value4=(value4+value1+value2+value3+sram_check)&1+3;
          sram_check=(sram_check<<1)+(sram_check>>7)+value1+value2+value3+value4;
        }
      }
    }</code>


    На экране HD44780 подключенном стандартным образом по 4-х битной шине во второй строке выводится номер итерации цикла, и 8 шестнадцатеричных цифр контрольных сумм. Первые 2 — тест SRAM, затем Flash, арифметика и program flow. Если все ок — то контрольная сумма должна получаться 12345678. Ошибка в контрольных суммах накапливается. Также код ошибки выводится морганием светодиода на плате: монотонное моргание — все ок, 1 вспышка — ошибка SRAM, 2 — Flash и т.д. При тестах на ~-100°C — обычно находил ошибку program flow тест, при -196°C — тест с чтением/записью SRAM памяти.

    Предполагалось, что при повышении напряжения мне придется отключить дисплей, и полагаться только на светодиод. Однако вышло наоборот — светодиод при температуре жидкого азота перестал работать (из-за расширения band-gap-а требуемое напряжение для зажигания стало выше напряжения питания, об этом ниже).



    Генератор тактовой частотыArduino по умолчанию работает от кварца. Кварцы на первой гармонике обычно работают не выше 30Мгц, потому с внешним генератором неизбежна. Чтобы не паять саму плату Ардуины — я отогнул 2 ноги, к котором подключается кварц, и припаял контакт к внешней тактовой частоте. Ну и нужно было изменить fusе-ы для работы от внешнего генератора, для чего нужен отдельный программатор (в моем случае — TL866CS MiniPro). Об этом я конечно подумал уже после отгибания ног, и в программатор микроконтроллер пришлось ставить с костылями. На снимке слева — виден также китайский модуль DCDC на LM2596, которым я изменял напряжение питания.



    Генератора сигналов до 100Мгц у меня конечно не было — недешевое это дело. Перестраиваемый генератор, способный генерировать в нужном мне диапазоне (16-100Мгц) со скважностью 50% удалось собрать только с 4-й попытки. Оказалось, многие генераторы на логических элементах — или имеют слишком низкую максимальную частоту, или нестабильны на высоких частотах (некоторые импульсы случайно становятся короче/шире). В конце концов следующая схема надежно генерировала во всем требуемом диапазоне. Резистор R1 на выходе — частичное последовательное терминировавшие, чтобы overshot тактового сигнала на стороне микроконтроллера был не такой страшный. Нам предстоит работа на повышенном напряжении, так и сжечь микросхему можно (при «резком» сигнале амплитудой 8V — мгновенные «выбросы» на стороне микроконтроллера были бы до 16 вольт).





    Особенности работы электроники при криогенных температурахПри охлаждении до -196 градусов — сильно падает сопротивление металлов. Например для меди — катушка имела сопротивление 56.3 Ома при комнатной температуре и только 6.6 Ома при охлаждении (падение в 8.5 раз).

    Поведение конденсаторов намного сложнее: электролитические конденсаторы при замерзании электролита теряют емкость в ~500'000 раз. Керамические конденсаторы — в зависимости от диэлектрика: самые дешевые Y5V — теряют почти всю емкость при охлаждении, X7R — теряют 66% емкости и NP0 (C0G) — изменение емкости не более 1% (но такие конденсаторы емкостью больше 1000 пФ — редкость). Соответственно, если развязочные конденсаторы по питанию были с диэлектриком Y5V — то схема может потерять стабильность при охлаждении. Проверить тип диэлектрика можно и при нагревании до 100-150 градусов — влияние на емкость примерно такое-же. Для исключения этой проблемы — прямо на ноги питания микроконтроллера были припаяны конденсаторы с диэлектриками X7R и NP0.

    Для полупроводников — увеличивается ширина запрещенной зоны, и изменяется мобильность электронов/дырок (тут зависимость сложная). На практике это приводит к тому, что например кремниевые диоды — имеют падения напряжения не 0.6-0.7 В, а 1.1. Это особенно касается аналоговых схем, в которых много биполярных транзисторов.

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


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

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

    Непосредственно разгон с драматичным началомПосле всех этих приготовлений — медленно заливаю Arduino жидким азотом, слышу как там похрустывают соединения, и вдруг — гаснет подсветка экрана, и затем плата «зависает». Я подумал было, что это конец. Затем выяснилось, что если немного приподнять плату над азотом, чтобы она так сильно не охлаждалась — подсветка загорается снова, и плата работает. С трудом удалось поразгонять, до ~50Мгц. Но конечно результат был не надежным, т.к. температура микроконтроллера была непостоянной.

    Внезапно, глядя на то, как плата останавливается при опускании в азот и продолжает работу при отогревании — пришла идея: а вдруг это срабатывает защита от слишком низкого напряжения питания? Отключил Brown-out detection — и микроконтроллер стал стабильно работать при опускании в жидкий азот! С экраном — оказалось, что подсветка была подключена к 3.3В линейному регулятору на плате (пины питания заканчивались) — и при снижении температуры у него видимо тоже толи защита срабатывала, толи напряжение сильно падало. Подключил напрямую к 5В — и тоже все заработало.

    Стабильная работы была около 50Мгц — и я начал повышать напряжение. Оказалось, что выше 8 Вольт — система переставала работать, а 7.5-8 Вольт обеспечивали абсолютно стабильную работу на частоте 65.3Мгц. Для сравнения, при комнатной температуре и 5В — максимально стабильная частота — 32.5Мгц, а при 8В — 37Мгц.

    На частоте 65Мгц тест стабильно отработал больше часа, суммарно на разгон ушло 3 литра азота.





    На воздухе — плата мгновенно покрывается инеем:


    На видео тест на частоте 65Мгц начинается на 7:12, вид работы Arduino под слоем жидкого азота — на 9.00.

    А остатки жидкого азота встретятся лицом к лицу с горячей водой:
    Резюме
    • Arduino под жидким азотом разгоняется и стабильно работает более часа на частоте 65.3Мгц, а на воздухе — только до 32.5-37Мгц. AVR короткое время спокойно работает при напряжении 8 Вольт.
    • Удалось разобраться как изменяются параметры электронных компонент при глубоком охлаждении: падение сопротивления металлов в ~8.5 раз, падение емкости конденсаторов (электролитов, керамики Y5V и немного X7R. Емкость NP0 не изменяется), увеличение ширины запрещенной зоны полупроводников (рост падения напряжения диодов, изменение цвета светодиодов, очень большие изменения в работе аналоговых схем)
    • При разгоне «больших» процессоров — нужно внимательно следить за температурой конденсаторов (электролитов и дешевых керамических с диэлектриком Y5V). Она не должна падать ниже нуля — даже если для этого придется устанавливать дополнительный подогрев. Иначе они потеряют почти всю емкость, и процессор будет терять стабильность.
    • Ни одна Arduino не пострадала в процессе написания статьи. После отогревания и высыхания — продолжила работать, как и раньше :-)
    PS. Из других экспериментов с жидким азотом — фосфоресценция сахара зеленым светом. А если будете разбивать фрукты — убирайте осколки ДО того, как они превратились в разбросанную по всей комнате фруктовую кашу

    PS. Если кто знает, где можно приобрести образцы сверхпроводников — напишите. То что я нашел — чудовищно дорого.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Ракета Grasshopper успешно взлетела на 250 м со смещением на 100 м

    Элон Маск и его компания SpaceX продолжают успешные эксперименты с ракетой Grasshopper. Ракета высотой с 10-этажное здание ранее сделала шесть успешных полётов, а во время седьмого эксперимента 13 августа 2013 года впервые осуществила манёвр со смещением в сторону на 100 м на высоте 250 м, после чего опустилась обратно в центр взлётной площадки.


    Grasshopper — экспериментальный проект для проверки ракетных двигателей SpaceX, которые в будущем предполагается использовать в различных аппаратах с вертикальным взлётом и посадкой, в том числе в многоразовых ракетах Falcon 9 и Falcon Heavy. Проект начали разрабатывать в 2011 году, а первые лётные испытания провели в 2012 году. С тех пор постепенно увеличивается высота и скорость полёта. До конца 2013 года SpaceX рассчитывает провести испытания на сверхзвуковых скоростях.

    После трёх лет испытаний компания Элона Маска планирует начать коммерческие полёты. Федеральное управление по гражданской авиации США уже дало разрешение SpaceX на 70 суборбитальных полётов в год. В перспективе, Маск надеется выиграть контракт НАСА на доставку грузов и астронавтов на Международную космическую станцию.

    Кроме SpaceX, разработку космических аппаратов ведут и другие частные компании. Например, компания Blue Origin Джеффа Безоса (основатель Amazon) разрабатывает многоразовый космический аппарат Dream Chaser. Его модель уже продули в аэротрубе, а прототип прошёл тесты на разгон и торможение на скоростях до 100 км/ч.




    Dream Chaser

    В конце концов, продолжается тестирование корабля SpaceShipTwo. Компания Virgin Galactic уже начала приём предварительных заказов на суборбитальные полёты от будущих туристов. На сегодняшний день 625 человек высказали желание заплатить $250 тыс. за возможность посмотреть на чёрное небо и испытать невесомость на несколько минут. Коммерческие рейсы SpaceShipTwo запланированы на 2014 год.


    SpaceShipTwo

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Интервью с владельцем Silk Road



    В номере журнала «Форбс» от 2-ого сентября 2013 года будет опубликована интересная статья: журналисту издания удалось взять интервью у главы крупнейшей онлайн- по продаже наркотических веществ и препаратов — «Шёлковый путь». Механизмы работы площадки обеспечиваются анонимными сетями с луковой маршрутизацией и криптографически защищенной валютой «Биткойн».

    Далось это действительно не без труда: предприниматель уровня Ужасного пирата Робертса не имеет права доверять ни незнакомцам, ни телефонным линиям, ни сетям мгновенного обмена сообщениями. Бесмысленно искать его контакты в «Скайпе» или пытаться устроить личную встречу: как заявил оператор площадки, он не контактирует в оффлайне даже с самыми доверенными лицами, и предложение встретиться в некой стране за пределами США было решительно отвергнуто. За владельцем «Шёлкового пути» ведётся охота на межгосударственном уровне, и он не может позволить себе рисковать.

    Общение происходило исключительно посредством системы сообщений и форума сайта, владельцем которого является Ужасный пират Робертс. Доступ к нему осуществлялся как и к любому .onion-сайту — через систему «Тор». Сетевое знакомство журналиста «Форбса» с человеком, выбравшим себе никнейм по имени персонажа романа Уильяма Голдмана (хотя, скорее это имя следовало бы трактовать как nom de guerre, боевой псевдоним) длилось восемь месяцев. Но общение не было постоянным: в один момент после вопиюще некорректного вопроса о его настоящем имени и гражданстве Ужасный пират прервал контакт на месяц.

    Человеку, столь тщательно скрывающемуся от незнакомцев, действительно есть чего опасаться. За последние 2,5 года «Шёлковый путь» вырос из скромного сайта в глубине сетей «Тора» до крупнейшей в мире торговой онлайн-площадки героина, амфетаминов, крэка, кокаина, ЛСД, экстази и марихуаны. Исследование студента Тринити-колледжа в Дублине показало, что ежедневно сайт испытывает 60 тыс. посещений. от ресурса Ужасного пирата по оценке Николаса Кристина составляли 1.2 млн. долларов в месяц в первой половине 2012 года. По оценкам «Форбса», сейчас доходы биржи составляют 45 млн. долларов в год.

    Управление по борьбе с наркотиками США не комментирует статус расследования этого случая, но в официальном заявлении они упоминают о том, что им известно о существовании столь активного сайта. Сенатор Чак Шумер требует немедленного закрытия биржи, расценивая её как наиболее бесстыдную попытку торговать наркотиками в сети.

    Закрытию и обнаружению владельцев «Шёлкового пути» мешает факт использования сетей луковой маршрутизации для доступа к сайту. Для оплаты товаров используется анонимная сеть криптографической валюты «Биткойн», которая не так давно была официально признана властями США в качестве денежных средств, подчиняющихся налогообложению. Именно положительные черты «Биткойна» — децентрализованность и опора на вычислительную сеть пользователей в качестве гаранта — позволили одержать победу над подразделениями по борьбе с наркотиками. Конечно, «Биткойн» хранит историю всех транзакций, но ничто не мешает воспользоваться одной из множества существующих компаний отмыва денег. Такая схема действительно помогает, «Биткойна» опасается даже ФБР. Доходы «Шёлкового пути» обеспечиваются комиссией с продаж товаров, которая составляет не более 10% и уменьшается по мере роста размера транзакций.

    Какова же позиция Ужасного пирата Робертса в отношении того, что он делает? Владелец биржи имеет либертарианские взгляды и считает, что он не только предоставляет для мелких дельцов и потребителей желаемое, но и выносит анархизм «тёмной сети» за её пределы и пределы налоговых и прочих регуляторов государств — эдакий Джулиан Ассанж со шприцем: «Мы не можем оставаться в тени вечно. Мы несём важную идею, и миру пришло время услышать её. […] То, что мы делаем, — не просто наркотики или «борьба с системой». Мы боремся за наши права как людей и отказываемся подчиниться, когда мы не совершили ничего дурного. […] «Шёлковый путь» — это лишь средство для донесения идеи. Всё остальное вторично.» В распространении информации и криптовалюте Робертс видит будущее ослабление роли государства.

    Политический апломб и стремление к рекламе усилились после появления у площадки Ужасного пирата конкурентов. Новый сайт, рекомендующий себя «фейсбуком майспейсоподобного «Шёлкового пути», называется Atlantis и имеет реальный маркетинговый бюджет и исполнительного директора. 26 июня этого года на «Ютубе» был опубликован рекламный ролик новой площадки. Свой же сайт Робертс никогда не рекламировал в открытую, полагаясь на сарафанное радио своих клиентов, даже идею сайта Silk Road Link с руководством по применению «Шёлкового пути» он взял у своих конкурентов. Видеоролик описывает бытовые проблемы курильщика марихуаны, отчаявшегося найти нового дилера после переезда. Обнаружив сетевой чёрный рынок в виде сайта «Атлантис», любитель «травки» получает желаемое. Видео было удалено на следующий день администрацией видеохостинга, но ролик успел получить почти 100 тыс. просмотров.


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

    «Биткойн» во многом помог развитию чёрного рынка, но также он столкнул Ужасного пирата с «Шёлковым путём». Дело в том, что текущий владелец биржи — не её основатель. Текущий её оператор обратил внимание на сайт почти сразу же после его создания в 2011 году, и однажды обнаружил уязвимость в безопасности кошелька, на котором хранились денежные средства биржи. Но вместо того, чтобы воспользоваться багом и украсть биткойны, хакер связался с владельцем и таким образом вошёл в его доверие. Постепенно контроль над биржей перешёл новому Ужасному пирату Робертсу, но и старый не остался без ничего: его доля была компенсирована, тем более он сам хотел передать этот пост. О новом владельце было объявлено в феврале 2012 года на форуме «Шёлкового пути». Уже тогда Ужасный пират стал жить согласно своему альтер-эго и начал публиковать манифесты о либертарианских идеалах торговой площадки.

    В обычной жизни Робертс скромен. Разумеется, он не тратит крупные суммы денег, не выделяясь среди людей со схожим достатком, хотя ему по карману куда более роскошная жизнь. Единственное, что он себе позволяет — это курение индийской конопли. Оператор биржи подобного размера прекрасно понимает, что в случае его поимки ему грозит пожизненное заключение. Робертс согласен продать «Шёлковый путь» лишь за число из как минимум 10 или 11 цифр.

    С появлением крупных денег неизбежно зарождение криминальных группировок, их контролирующих. Также возможны взломы, как это уже случалось в конце апреля этого года, когда «Шёлковый путь» ушёл в оффлайн на неделю. Использованная уязвимость позволяла говорить о высоком навыке взлома злоумышленников. Случилось это через несколько недель после запуска «Атлантиса». Бирже также угрожают правоохранительные органы: не так давно был закрыт сервис анонимных платежей Liberty Reserve, несколько дней назад была обнаружена уязвимость в сети «Тор», позволившая задержать распространителей детской порнографии. Будущее «Шёлкового пути» остаётся туманным и неопределенным.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    9 интересностей и полезностей для веб-разработчика

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

    Prepros


    Великолепное приложение препроцессор для CSS, JS. Компилирует файлы следующих типов: LESS, Sass, SCSS, Stylus, Jade, Slim, Coffeescript, LiveScript, Haml. Минифицирует JS на лету, при каждом изменении файла. Оптимизирует изображения. Доступен для Windows и Mac, а также как расширение для Chrome. Плюс ко всему создает HTTP сервер, для тестирования сайта на разный устройствах. Бесплатная замена CodeKit'у и Ghostlab'у вместе взятых, что в сумме позволит Вам сэкономить $75.


    Dimensionsapp
    Говоря о тестировании отображения веб приложений на разных экранах, хочется сказать про онлайн сервис Dimensionsapp.

    Brackets

    Open source редактор от Adobe написанный на JavaScript специально для веб-разработчиков. Приятный дизайн, встроенное обновление страницы без перезагрузки (аналоги: Emmet LiveStyle и LiveReload), просмотр стилей для HTML элементов из редактора по Cmd/Ctrl + E и множество плагинов, которых будет еще больше.


    VerbalExpressions

    Кто не любит писать регулярные выражения? Что если проверка на URL в JS будет выглядеть следующим образом:
    <code class="javascript">// Create an example of how to test for correctly formed URLs
    var tester = VerEx()
                .startOfLine()
                .then( "http" )
                .maybe( "s" )
                .then( "://" )
                .maybe( "www." )
                .anythingBut( " " )
                .endOfLine();
    
    // Create an example URL
    var testMe = "https://www.google.com";
    
    // Use RegExp object's native test() function
    if( tester.test( testMe ) ) alert( "We have a correct URL "); // This output will fire
    else alert( "The URL is incorrect" );
    </code>
    Библиотека также существует для: Ruby, C#, Python, Java, Groovy, , Haskell, C++, Objective-C.
    GitHub

    HTML.js

    Относительно недавно я рассказал на Хабре про Voyeur.js с очень приятным синтаксисом для работы с DOM. HTML.js это форк Voyeur'а с рядом новых методов: .
    each(), remove(), ify(), ._other(), _fn()

    image
    GitHub

    LiveScript

    LiveScript — это «язык который компилируется в JavaScript, косвенный потомок CoffeeScript». Синтаксис, возможно, не очень привлекательный на первый взгляд, зато сам LiveScript очень и очень функциональный:
    <code class="javascript">LiveScript
    
    take = (n, [x, ...xs]:list) -->
      | n <= 0     => []
      | empty list => []
      | otherwise  => [x] ++ take n - 1, xs
    
    take 2, [1 2 3 4 5] #=> [1, 2]
    
    take-three = take 3
    take-three [3 to 8] #=> [3, 4, 5]
    
    # Function composition, 'reverse' from prelude.ls
    last-three = reverse >> take-three >> reverse
    last-three [1 to 8] #=> [6, 7, 8]
    </code>
    А вот сколько бы нам с Вами понадобилось JS кода
    <code class="javascript">var take, takeThree, lastThree, slice$ = [].slice;
    take = curry$(function(n, list){
      var x, xs;
      x = list[0], xs = slice$.call(list, 1);
      switch (false) {
      case !(n <= 0):
        return [];
      case !empty(list):
        return [];
      default:
        return [x].concat(take(n - 1, xs));
      }
    });
    take(2, [1, 2, 3, 4, 5]);
    takeThree = take(3);
    takeThree([3, 4, 5, 6, 7, 8]);
    
    
    lastThree = function(){
      return reverse(takeThree(reverse.apply(this, arguments)));
    };
    lastThree([1, 2, 3, 4, 5, 6, 7, 8]);
    function curry$(f, bound){
      var context,
      _curry = function(args) {
        return f.length > 1 ? function(){
          var params = args ? args.concat() : [];
          context = bound ? context || this : this;
          return params.push.apply(params, arguments) <
              f.length && arguments.length ?
            _curry.call(context, params) : f.apply(context, params);
        } : f;
      };
      return _curry();
    }
    </code>


    git-html5.js

    Реализация git на JavaScript в вашем браузере. Применение я вижу только в примере работы вышеописанного Brackets (на JavaScript) как расширения для Chrome, но уверен, что это полезная штука для настоящих гиков.
    GitHub
    Демо-страничка с демонстрацией Commit, Push, Pull и Branching

    Краудфандинг: Ghost — Just a Blogging Platform

    Насколько я знаю, это первая , которая будет разработана силами краудфандинга. Автор проекта John O'Nolan собрал уже $400 000 на Kickstarter, что составляет 785% требуемой суммы. Ghost — это открытый проект, замечательный дизайн и очень удобный адаптивный интерфейс.

    Infogram


    Инфографика способна не только организовать большие объёмы информации, но и более наглядно показать соотношение предметов и фактов во времени и пространстве, а также продемонстрировать тенденции. Inforgram — очень простой инструмент для создания инфографики. Возможность импортировать данные в форматах XLS, XLSX и CSV. Если я не ошибаюсь, то это единственный сервис для создания интерактивной инфографики. Добавляйте диаграммы, , фото, видео. Сервис выполнен в формате социальной сети. Делитесь, шарьте, используйте embed code для своих сайтов.


    Понравилась ли Вам подборка?


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 206 человек. Воздержалось 60 человек.


    Да



    Нет


    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Уязвимость интерфейса мозг-компьютер



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

    Нейрокомпьютерный интерфейс как и любой другой интерфейс ввода данных состоит из двух компонент: устройства ввода и обеспечивающего его работу программного обеспечения. В данном случае роль первого исполняет надеваемый на голову электроэнцефалограф с группой датчиков на черепе пользователя, а поступающие от них данные обрабатывает драйвер на ПК. Как правило, стоимость подобных интерфейсов позволяла находить применения интерфейсам мозг-компьютер лишь в медицине, но в последнее время о себе заявили устройства Emotiv и Neurosky, стоимость которых была значительно ниже.

    Оба из упомянутых коммерчески доступных массовому пользователю интерфейсов мозг-компьютер имеют API, позволяющие сторонним разработчикам создавать свои приложения, использующие возможности одностороннего обмена между мозгом и компьютером. Исследователи безопасности из университетов Оксфорда и Женевы, Калифорнийского университета в Беркли так и поступили. Их программа была создана с целью выяснения приватной информации пользователя: местоположения его дома, ПИН-кода его банковской карточки, используемого банка, даты рождения и т. п. Затем исследователи прогнали свою программу на 28 испытуемых, не подозревавших, что под угрозу ставится их частная жизнь, и в 10—40% случаев попытки выяснить важные детали из жизни подопытных были успешными.



    Для извлечения нужной информации был использовано то, что широко известно как реакция P300 — специфический образец мозговых волн, который проявляется при распознавании мозгом чего-либо значимого или нужного для текущей задачи — лица человека, слесарного или любого другого инструмента. По сути, программа демонстрировала различные изображения географических карт, банков и ПИН-кодов кредиток, в то же время шла запись реакции мозга испытуемых, отмечая каждый раз, когда реакция P300 была положительной. Затем с неплохой точностью можно было определить используемый банк испытуемого, где он живёт и так далее.

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



    Исследовательская (PDF)

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    PayPal начнёт работать с рублями уже с 17 сентября



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

    Переводить деньги на свой счет в российском банке смогут как организации, так и индивидуальные пользователи. Дополнительную комиссию за это PayPal взимать не будет, равно как и не установит лимит на переводимые средства.

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

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

    В мае этого года PayPal получил лицензию небанковской кредитной организации (НКО) Центробанка России. Лицензия позволяет ООО «ПэйПал Ру» осуществлять банковские операции со средствами в рублях и иностранной валюте.

    Roem отмечает, что с получением легального статуса в России PayPal ужесточил требования к идентификации пользователей: у физических лиц для подтверждения личности требуют предоставления отсканированных копий паспорта, а у владельцев бизнес-аккаунтов — целый список документов, сопутствующих деятельности юридического лица на территории России.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Выбираем время с помощью нового TimePickerDialog

    Просматривая ленту у себя в G+, наткнулся на сообщение, что в последней версии приложения Календарь на Android-устройствах используется новое диалоговое окно для выбора времени. Запустив приложение на своем планшете Nexus 7 с Android 4.3, я убедился, что это действительно так. Но меня как разработчика больше заинтересовала фраза, что исходный код диалогового окна доступен по адресу https://android.googlesource.com/platform/frameworks/opt/datetimepicker/+/master/. Я решил поковыряться just for fun.

    Статья рассчитана на более-менее опытных разработчиков, поэтому сильно разжевывать объяснения не буду.
    Я не стал клонировать Git- репозиторий, а просто стал копировать в свой тестовый проект различные классы и ресурсы. Для начала в проекте я создал новый пакет и скопировал все классы из папки src/com/android/datetimepicker/time/. Также скопировал два класса из папки src/com/android/datetimepicker: Utils.java и AccessibleTextView.java. При желании вы можете скопировать себе и другие классы, но для создания диалога выбора времени этого вполне достаточно. Затем скопировал все необходимые ресурсы: строки, цвета, размеры, темы и русскую локализацию. Последний штрих — в манифесте нужно прописать разрешение на использование вибромотора.
    На этом подготовительные работы закончены.
    Новое диалоговое окно построено на основе фрагмента DialogFragment. Набросаем простую разметку с единственной кнопкой с атрибутом android:onClick=«onClick», которая будет вызывать диалоговое окно. И напишем код:
    <code class="java">	public void onClick(View v) {
    		openDialog();
    	}
    
    	void openDialog() {
    		TimePickerDialog timepickerdialog = TimePickerDialog.newInstance(
    				new OnTimeSetListener() {
    
    					@Override
    					public void onTimeSet(RadialPickerLayout view,
    							int hourOfDay, int minute) {
    						// TODO Auto-generated method stub
    						Toast.makeText(getApplicationContext(),
    								"Вы выбрали время " + hourOfDay + ":" + minute,
    								Toast.LENGTH_LONG).show();
    
    					}
    				}, 19, 17, false);
    		timepickerdialog.show(getFragmentManager(), "myDialogFragment");
    	}
    </code>

    Пробуем запустить приложение в эмуляторе:



    Ура, заработало!
    Переключаем устройство на русский язык и смотрим на результат



    Откровенно говоря, не впечатляет — буквы не влезают. Но с другой стороны я предпочитаю 24-часовой формат. Поэтому меняем у OnTimeSetListener последний параметр с false на true и запускаем проект снова.





    По картинкам не совсем понятно, как это работает, поэтому объясню словами. Сначала появляется часовой круг с двумя вписанными окружностями из цифр. Внутренняя окружность отвечает за часы первой половины дня, внешняя — за вторую половину. Когда пользователь выбрал нужный час и отпускает палец, то часовой круг при помощи анимации меняется на минутный круг, у которого числа идут с интервалом в 5 минут. Пользователь может выбрать промежуточную позицию между двумя делениями, чтобы выбрать более точное время. Если нужно снова переключиться на часовой круг, то достаточно «тапнуть» по часам (которые сейчас имеют серый неактивный цвет) в верхней части диалога.
    Если время выбрано окончательно, то щелкаем по кнопке Готово и возвращаемся в основную активность. В моем примере всплывающее сообщение Toast сообщит о выбранном времени.
    На мой взгляд, новое диалоговое окно выглядит симпатично. Хотелось бы, чтобы данная новинка была доступна в виде отдельной библиотеки или встроена в систему Android. Впрочем, как видите, при желании вы сами можете данный функционал в своих проектах.
    Удачного вам программирования!

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Perl6 — Перегрузка операторов

    1. Особенности работы с переменными и литералами в Perl6
    2. Perl6 — Операции над переменными, анонимные блоки
    3. Perl6 — Условные операторы, циклы
    4. Perl6 — с функциями
    5. Perl6 — Классы
    6. Perl6 — Ввод-вывод, модули
    7. Perl6 — Комментарии, пробельные символы, скобки
    Однажды я уже писал статью о функциях и об особенностях их использования (№4). Сейчас я хочу рассмотреть одну из их разновидностей — операторов.


    Начнем мы, пожалуй, с инфиксных операторов:
    Примером инфиксных операторов является оператор '+'
    <code>sub infix:<MyNewOperator> (Int $a, Str $b)
    {
      return "Call: $a + $b";
    }
    
    say 10 MyNewOperator "abc";
    </code>
    В результате мы увидем на экране
    <code>Call: 10 + abc
    </code>
    Как видите, мы не ограничены в именах операторов, как это есть в с++ — мы можем добавлять новые или изменять уже существующие, просто поменяв «MyNewOperator» на '+'. В результате мы получим оператор сложения, который вместо приведения типов и склеивания двух строк будет выдавать строку в указанном нами формате.

    Так же хотелось бы дополнить, что ради эксперимента я попытался добавить ещё и третий аргумент для инфиксного оператора, и такой оператор даже успешно скомпилировался, но единственный способ вызова такого оператора ничем не отличается от вызова обычной функции:
    <code>sub infix:<MyNewOperator> (Int $a, Str $b, $c)
    {
      return "Call: $a + $b, $c";
    }
    
    say infix:<MyNewOperator>(1, "abc", 5);
    </code>
    Смысла в создании операторов и потом вот такого использования я не вижу, поэтому в дальнейшем отступать от «сигнатуры параметров» я не буду.

    Перейдем к следующему типу операторов — префиксному.
    Наглядным примером является оператор отрицания логического выражения '!' который мы просто для проверки перегрузим для целых чисел
    <code>sub prefix:<!> (Int $a)
    {
      return "Call: prefix ! $a";
    }
    
    say !1;
    </code>
    Стоит так же заметить, что мы опять же не ограничены именами уже существующих префиксных операторов. Таким образом я даже смог перегрузить оператор '.', что создавало очень необычный вид привызове такого оператора. По этому поводу мне даже вспомнилась где-то прочитанная шуточная фраза «В Perl6 можно будет пергружать операторы, блоки, все, и даже перегружать перегрузку». Шутка шуктой, но префиксный оператор точка как-то уж заставляет задуматься =)

    Но пора переходить к других вещам — постфиксным операторам:
    Опять же вспомнилась одна статья на тему мелкого шрифта и одного банка:
    <code>sub postfix:<*> (Int $a)
    {
      return "See $a paragraph in document A";
    }
    
    say "We can give you \$1_000_000 just for lulz!";
    say 1*;
    </code>

    В результате увидим
    <code>We can give you $1_000_000 just for lulz!
    See 1 paragraph in document A
    </code>

    Опять же касательно всех предидущих типов операторов — по сути мы ограничены в именах операторов только тем, что компилятор должен понять где конец оператора и где начало операнда. Так что не стоит особо изощряться при выборе имени оператора.
    И напоследок, пока мы не продолжили, не стоит забывать, что оператор фактически таже функция, поэтому если вы хотите сделать ещё один такой же постфиксный оператор '*' но для строк, то в обоих случаях использования нужно добавить ключевое слово 'multi'.

    Но мы всетаки перейдем к следующей категории — перегрузка скобок:
    <code>sub circumfix:<(( ))> (Int $a)
    {
      return "<$a>";
    }
    
    say ((1));
    </code>

    В результате мы получим
    <code><1>
    </code>

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

    Однако перейдем к следующему типу — «постфиксные скобки»
    Как я ни пытался заставить компилятора перегрузить этого оператора для строки или числа, мне выдавалось сообщение что такого метода просто нету у строк. А примеры которые я находил в интернете были оформлены в виде методов для классов. Из этого я могу предположить, что получиться это сделать только если создам новый класс, поэтому пока что примеры использования попридержим до следующих статей, однако если интересно то можете попытать компилятора на эту тему.

    На последок также хотел добавить, что заметил работающую проверку типа возвращаемого значения функцией:
    <code>sub Func($a) of Int
    {
       return $a;
    }
    </code>
    Не смотря на то что функция может принимать любые типы операндов, на возврате значения ошибка будет происходить на этапе выполнения, если будет передано не целое число, а например строка или дробное значение. На сколько я помню в последний раз, когда я проверял, эта возможность не работала.

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Перевод] Оформление кода, оптимизация процесса проверки качества кода

    JavaScript, the winning style


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

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

    В отличие от Питона у которого есть единый свод правил «Style Guide for Python Code», у языка JavaScript такого нет. Однако на выбор есть целых 6 популярных гайдов:


    Помимо гайдов, не стоит так же забывать об автоматических анализаторах кода, таких, например, как JSLint и JSHint. И в них уже заложены свои настройки.Вопрос в том, какой же все-таки максимально правильный способ писать код на JavaScript, который был бы актуален и максимально соответствовал бы большинству рекомендаций? Давайте попробуем объединить большинство рекомендаций в этой статье и подумаем как можно оптимизировать процесс проверки качества кода.

    Оформление

    Отступ
    • 2 пробела, не больше и без табуляции: Google, npm, Node.js, Idiomatic
    • Табуляция: jQuery
    • 4 пробела: Crockford

    Пробел между аргументами и выражением
    • Без пробела, как на примере: Google, npm, Node.js

      <code class="javascript">project.MyClass = function(arg1, arg2) {
      </code>
    • С пробелом, как на примере: Idiomatic, jQuery

      <code class="javascript">for ( i = 0; i < length; i++ ) {
      </code>
    • Без особого мнения: Crockford

    Многие гайды так же напоминают, чтобы не было пробелов в конце строк (trailing spaces)

    Длина строки
    • Максимум 80 знаков: Google, npm, Node.js, Crockford
      При переносе строк, отступ не обязательно должен быть равен 2, если вам надо, например, перенести на следующую строку аргументы функции, то выровнять их можно по тому месте где стоит первый аргумент. Как другой вариант, можно так же использовать 4 пробела вместо 2, когда перенесите длинные строки.

    • Без особого мнения: jQuery, Idiomatic

    Точка с запятой
    • Всегда использовать точку с запятой: Google, Node.js, Crockford
    • Не использовать в некоторых ситуациях: npm
    • Без особого мнения: jQuery, Idiomatic

    Комментарии:
    • JSDoc: Google, Idiomatic
    • В Idiomatic Style Guide так же разрешены более простые комментарии, но JSDoc предпочтительнее
    • Без особого мнения: npm, Node.js, jQuery, Crockford

    Кавычки
    • Предпочтительнее одинарные кавычки. Лучше
      'value', чем "value":
      Google, Node.js
    • Двойные кавычки ": jQuery
    • Без особого мнения: npm, Idiomatic, Crockford

    Декларирование переменных
    • Одна переменная на одной строке: Node.js

      <code class="javascript">var foo = '';
      var bar = '';
      </code>
    • Несколько переменных, разделяемые запятыми в конце строки, как на примере: Idiomatic, jQuery

      <code class="javascript">var foo = "",
         bar = "",
         quux;
      </code>
    • Запятая в начале строки: npm

      <code class="javascript">var foo = ""
        , bar = ""
        , quux;
      </code>
    • Без особого мнения: Google, Crockford

    Скобки
    • Ставьте открывающую скобки на той же строке: Google, npm, Node, Idiomatic, jQuery, Crockford

      <code class="java">function thisIsBlock() {
      </code>
      Это подразумевает, что скобки следует использовать всегда, даже в ситуации, где их можно опустить.

    • В npm гайде указано, что скобки нужно использовать только в случае, когда тело функции переносится на следующую строку.

      <code class="javascript">if (foo) bar()
      while (foo) {
        bar()
      }
      </code>

    Глобальные переменные
    • Не используйте глобальные переменные: Google, Crockford
      Google:
      Global name conflicts are difficult to debug, and can cause intractable problems when two projects try to integrate. In order to make it possible to share common JavaScript code, we’ve adopted conventions to prevent collisions.
      Перевод:
      Глобальные переменные сложнее отлаживать, и они могут стать причиный нетривиальных проблем, когда двум проектам надо интегрироваться. Да бы совместить весь общий код на JavaScript, мы составили соглашение, чтобы предотвратить возможные противоречия.


    • Crockford считает, что глобальные переменные не нужно использовать вовсе.
    • Без особого мнения: Idiomatic, jQuery, npm, Node

    Имена


    Переменные
    • Первое слово с маленькой буквы, все последующие с большой: Google, npm, Node, Idiomatic

      <code class="javascript">var foo = "";
      var fooName = "";
      </code>

    Константы

    • Все слово большими буквами: Google, npm, Node

      <code class="javascript">var CONS = 'VALUE';
      var CONSTANT_NAME = 'VALUE';
      </code>
    • Без особого мнения: jQuery, Idiomatic, Crockford

    Функции
    • Первое слово с маленькой буквы, все последующие с большой (camelCaps): Google, npm, Node, Idiomatic

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

      <code class="javascript">function veryLongOperationName
      function short()..
      </code>

      Использыйте слова is, set, get:

      <code class="javascript">function isReady()
      function setName()
      function getName()
      </code>
    • Без особого мнения: jQuery, Crockford

    Массивы
    • Используйте множественную форму слова: Idiomatic

      <code class="javascript"> var documents = [];
      </code>
    • Без особого мнения:Google, jQuery, npm, Node, Crockford

    Объеты и классы
    • Используйте как в примере: Google, npm, Node

      <code class="javascript">var thisIsObject = new Date;
      </code>
    • Без особого мнения: jQuery, Idiomatic, Crockford

    Другое
    Используйте all-lower-hyphen-css-case для многосоставных названий файлов и настроек: npm

    Используйте JSHint и .jshintrc файл

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

    <code class="javascript">{
      "camelcase" : true,
      "indent": 2,
      "undef": true,
      "quotmark": "single",
      "maxlen": 80,
      "trailing": true,
      "curly": true
    }
    </code>

    Во все файлы, которые обрабатываются браузером добавляем:

    <code class="javascript">/* jshint browser:true, jquery:true */
    </code>

    В файлы Node.js добавляем:

    <code class="javascript">/*jshint node:true */
    </code>

    Во все типы JS файлов, так же лучше добавить:

    <code class="javascript">'use strict';
    </code>

    Это повлияет и на JSHint и на обработчика JavaScript в целом, который станет менее терпимым к ошибкам, но будет работать быстрее. Почитать больше о 'use strict' (внешняя ссылка)

    Автоматическая проверка кода JSHint перед git commit

    Если вы хотите быть уверены в том что все ваши JS файлы прошли проверку и следуют общему стилю, который вы определили в .jshintrc. То добавьте эти строки в ваш .git/hooks/pre-commit файл. Теперь перед тем как закомитить изменения, скрипт будет проверять только измененные файлы на нарушения стилистики кода. И если таковые имеются, то операция будет прервана.

    <code class="bash">#!/bin/bash
    # Pre-commit Git hook to run JSHint on JavaScript files.
    #
    # If you absolutely must commit without testing,
    # use: git commit --no-verify
    
    filenames=($(git diff --cached --name-only HEAD))
    
    which jshint &> /dev/null
    if [ $? -ne 0 ];
    then
      echo "error: jshint not found"
      echo "install with: sudo npm install -g jshint"
      exit 1
    fi
    
    for i in "${filenames[@]}"
    do
    	if [[ $i =~ \.js$ ]];
    	then
    		echo jshint $i
    		jshint $i
    		if [ $? -ne 0 ];
    		then
    			exit 1
    		fi
    	fi
    done
    </code>

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

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

    Оригинальная статья: (http://seravo.fi/2013/javascript-the-winning-style)


    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Promise-ы в AngularJS

    Одной из ключевых составляющих практически любого веб-приложения является взаимодействие с сервером. В больших приложениях это далеко не один запрос. При этом запросы часто необходимо объединять для последовательного или параллельного выполнения, а часто сочетать и то и другое. Кроме того, большие приложения обычно имеют многослойную архитектуру — обертка над RESTFul API => бизнес-сущности => более комплексная бизнес-логика (разбиение условно для примера). И на каждом слое необходимо принять данные в одном формате и передать на следующий слой уже в другом.

    Вот со всеми этими задачами могут помочь справиться Promise-ы.

    За подробностями добро пожаловать под кат.


    Promise-ы предоставляют интерфейс для взаимодействия с объектами, содержащими результат выполнения некоторой операции, время окончания которой неизвестно. Изначально любой promise не разрешен (unresolved) и будет разрешен либо с определенным значением (resolved), либо отвергнут с ошибкой (rejected). Как только promise становится разрешен или отвергнут, его состояние уже не может измениться, что обеспечивает неизменность состояния в течение какого угодно числа проверок. Что не означает, что на разных этапах проверок вы получите одно и тоже значение.

    Кроме того, promise-ы можно объединять как для последовательного, так и для параллельного исполнения.

    Далее все описание будет построено на базе AngularJS 1.1.5, а все примеры будут исполнены в виде тестов.

    Итак, что из себя представляет promise? Это объект с двумя методами:
    • then(successCallback, errorCallback)
      ;
    • always(callback)
      ;

    Что в AngularJS вернет вам promise?
    • $http
      — сервис для выполнения AJAX-запросов;
    • $timeout
      — AngularJS-обертка над
      setTimeout
      ;
    • различные методы
      $q
      — сервиса для создания своих deferred-объектов и promise-ов.

    Далее последовательно пройдемся по всем вариантам работы с promise-ами.

    Простейшее использование


    <code class="javascript">    var responseData;
        $http.get('http://api/user').then(function(response){
            responseData = response.data;
        });
    
    </code>

    Ничего интересного — callback и все. Но надо же от чего-то отталкиваться в изложении?.. :-)

    Возврат значения из обработчиков


    <code class="javascript">    var User = function(data){
            return angular.extend(this, data);
        };
        $httpBackend.expectGET('http://api/user').respond(200, {
            result: {
                data: [{name: 'Artem'}],
                page: 1,
                total: 10
            }
        });
    
        var data = {};
        $http.get('http://api/user').then(function(response){
            var usersInfo = {};
    
            usersInfo.list = _.collect(response.data.result.data, function(u){ return new User(u); });
            usersInfo.total = response.data.result.total;
    
            return usersInfo;
        }).then(function(usersInfo){
            data.users = usersInfo;
        });
    </code>

    Благодаря такой цепочке
    then
    -ов можно строить многослойное приложение. ApiWrapper сделал запрос, выполнил общие обработчики ошибок, отдал данные из ответа без изменений на следующий слой. Там данные преобразовали нужным образом и отдали на следующий. И т.д.

    Любое возвращаемое значение из
    then
    придет в
    success
    -
    callback 
    следующего
    then
    . Не вернули ничего — в
    success-callback
    придет undefined (см. тесты).

    Чтобы сделать
    reject
    — необходимо вернуть
    $q.reject(value)
    .
    <code class="javascript">    $httpBackend.expectGET('http://api/user').respond(400, {error_code: 11});
    
        var error;
        $http.get('http://api/user').then(
            null,
            function(response){
                if (response.data && response.data.error_code == 10){
                    return {
                        list: [],
                        total: 0
                    };
                }
    
                return $q.reject(response.data ? response.data.error_code : null);
            }
        ).then(
            null,
            function(errorCode){
                error = errorCode;
            }
        );
    </code>

    Цепочки вызовов

    <code class="javascript">    $httpBackend.expectGET('http://api/user/10').respond(200, {id: 10, name: 'Artem', group_id: 1});
        $httpBackend.expectGET('http://api/group/1').respond(200, {id: 1, name: 'Some group'});
    
        var user;
        $http.get('http://api/user/10').then(function(response){
            user = response.data;
            return $http.get('http://api/group/' + user.group_id);
        }).then(function(response){
            user.group = response.data;
        });
    </code>
    Это позволит избежать пирамидального кода, сделать код более линейным, а значит более читабельным и простым в поддержке.

    Параллельное выполнения запросов с ожиданием всех

    $q.all(...)
    принимает массив или словарь promise-объектов, объединяет их в один, который будет разрешен, когда разрешатся все promise, или отвергнут с ошибкой, когда хотя бы один promise будет отвергнут. При этом значения придут в success-callback либо в виде массива, либо в виде словаря в зависимости от того, как был вызван метод
    all
    .

    <code class="javascript">    $httpBackend.expectGET('http://api/obj1').respond(200, {type: 'obj1'})
    
        var obj1, obj2;
        var request1 = $http.get('http://api/obj1');
        var request2 = $timeout(function(){ return {type: 'obj2'}; });
        $q.all([request1, request2]).then(function(values){
            obj1 = values[0].data;
            obj2 = values[1];
        });
    
        expect(obj1).toBeUndefined();
        expect(obj2).toBeUndefined();
    
        $httpBackend.flush();
        expect(obj1).toBeUndefined();
        expect(obj2).toBeUndefined();
    
        $timeout.flush();
        expect(obj1).toEqual({type: 'obj1'});
        expect(obj2).toEqual({type: 'obj2'});
    </code>

    <code class="javascript">    $q.all({
            obj1: $http.get('http://api/obj1'),
            obj2: $timeout(function(){ return {type: 'obj2'}; })
        }).then(function(values){
            obj1 = values.obj1.data;
            obj2 = values.obj2;
        });
    </code>

    $q.when

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

    <code class="javascript">    spyOn(UserApi, 'get').andReturn($q.when({id: 1, name: 'Artem'}));
    
        var res;
        UserApi.get(1).then(function(user){
            res = user;
        });
    
        $rootScope.$digest();
        expect(res).toEqual({id: 1, name: 'Artem'});
    </code>

    Обратите внимание, что для разрешения promise-ов должен быть выполнен хотя бы один
    $digest
    цикл.

    Создание своих
    deferred
    -объектов

    $q
    -сервис также позволяет обернуть любую асинхронную операцию в свой deferred-объект с соответствующим ему promise-объектом.
    <code class="javascript">    var postFile = function(name, file) {
            var deferred = $q.defer();
    
            var form = new FormData();
            form.append('file', file);
    
            var xhr = new XMLHttpRequest();
            xhr.open('POST', apiUrl + name, true);
            xhr.onload = function(e) {
                if (e.target.status == 200) {
                    deferred.resolve();
                } else {
                    deferred.reject(e.target.status);
                }
                if (!$rootScope.$$phase) $rootScope.$apply();
            };
            xhr.send(form);
    
            return deferred.promise;
        };
    </code>

    Ключевые моменты здесь:
    • создание своего deferred объекта:
      var deferred = $q.defer()
    • его разрешение в нужный момент:
      deferred.resolve()
    • или
      reject
      в случае ошибки:
      deferred.reject(e.target.status)
    • возврат связанного promise-объекта:
      return deferred.promise

    Особенности AngularJS

    Во-первых, $q-сервис реализован с учетом dirty-checking в AngularJS, что дает более быстрые resolve и reject, убирая ненужные перерисовки браузером.
    Во-вторых, при интерполяции и вычислении angular-выражений promise-объекты интерпретируются как значение, полученное после resolve.
    <code class="javascript">    $rootScope.resPromise = $timeout(function(){ return 10; });
    
        var res = $rootScope.$eval('resPromise + 2');
        expect(res).toBe(2);
    
        $timeout.flush();
        res = $rootScope.$eval('resPromise + 2');
    
        expect(res).toBe(12);
    </code>

    Это означает, что если следить за изменением переменной через строковый
    watch
    , то в качестве значения будет приходить именно resolved-значение.
    <code class="javascript">    var res;
        $rootScope.resPromise = $timeout(function(){ return 10; });
        $rootScope.$watch('resPromise', function(newVal){
            res = newVal;
        });
    
        expect(res).toBeUndefined();
    
        $timeout.flush();
        expect(res).toBe(10);
    </code>
    Исключение составляет использование функции. Возвращаемое из нее значение будет использовано как есть, т.е. это будет именно promise-объект.
    <code class="javascript">    $rootScope.resPromise = function(){
            return $timeout(function(){ return 10; });
        };
    
        var res = $rootScope.$eval('resPromise()');
    
        expect(typeof res.then).toBe('function');
    </code>

    Понимание этого важно при написании различных loading-виджетов, loading-директив для кнопок и т.п.

    AngularJS 1.2.0 — что нового в promise-ах

    • catch(errorCallback)
      как укороченный синоним для
      promise.then(null, errorCallback)
      ;
    • для большей схожести с Q
      finally(callback)
      переименован в
      finally(callback)
      ;
    • и самое существенное — поддержка нотификации в deferred- и promise-объектах, что удобно использовать для извещения о прогрессе и т.п. Теперь полная сигнатура
      promise.then
      выглядит как
      then(successCallback, errorCallback, progressCallback)
      , а у
      deferred
      появился метод
      notify(progress)
      .

    И напоследок скриншот выполненных тестов из WebStorm 7 EAP. Все же приятную добавили интеграцию с karma.


    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Ад с учётными записями — почему в одной компании пользователей было в 3 раза больше, чем сотрудников

    Прыдстория. В одной производственной компании было около двух десятков(!) кадровых баз. Это базы обособленных подразделений, и в каждой по несколько сотен человек. Всего около 10 тысяч сотрудников. Системный администратор работает грамотный, есть рабочая MS Active Directory.

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

    Параллельно админ понял ещё одну страшную вещь: в компании по факту работает примерно в три раза меньше людей, чем учёток у него в системе. Почему? Да всё просто: учётки заводились по письменным заявкам, а при увольнениях и переводах обновлять статус зачастую забывали.

    В этот момент мы начали работать над внедрением общего решения по управлению учетными записями и правами доступа, IdM. Для начала пришлось избавиться от раздробленности и свести все кадровые базы в одну промежуточную кадровую систему. Её связали с Active Directory через новый центр-репозиторий. Потом подключили к репозиторию остальные бизнес-системы вот так:


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

    Например, были учётки А. М. Иванова и А. М. Ивaнова (визуально – один сотрудник, но у второго буква a в фамилии английская: либо ошибка, либо кто-то специально его «клонировал»).

    Затем автоматизировали процесс назначения прав по документам кадровиков. Сделали портал самообслуживания, где сотрудники могли запросить доступ, куда было нужно. И уже не админ, а руководитель соответствующего подразделения его подтверждал. На аудит и понимание процессов ушло месяца два, ещё два на допиливание софта и тесты, последний — на внедрение и обучение IT-специалистов.

    Вот примерно так. История эта в целом реальная, но некоторые детали я специально изменил, чтобы не раскрывать заказчика. Самое интересное в ней то, что мало кто, оказывается, вообще понимал, как работают IdM-системы. Поэтому я и пишу этот топик.

    Общее об IdM

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

    С этим можно жить, увеличивая количество ручных операций, а можно настраивать IdM — систему управления идентификационными данными и правами доступа.

    Как это выглядит? Довольно красиво: например, при всё том же переводе сотрудника из одного подразделения в другое, вы обновляете его данные в одном репозитории. Дальше, например, в 1С меняются права, в корпоративном телефонном справочнике меняется должность, в бизнес-приложении обновляется учётка, в системе документооборота появляются новые связи по бизнес-процессам. И так далее.

    Итак, если ваша компания достаточно большая, то есть три варианта развития ситуации:
    С учётками наблюдается некоторый хаос. Например, когда приходит на работу сотрудник, ему необходимо предоставить доступ во множество информационных систем. Первые пару дней он может вообще не использовать корпоративные ресурсы, либо сидеть с учётки предшественника, что не очень хорошо. Во-вторых, если всё делается вручную — будут ошибки, типа избыточных прав в ряде систем. В-третьих, если нет точного процесса, многое будет завязано на конкретных людей, при повышении или уходе которых придётся заново восстанавливать систему управления доступами. Когда такие звоночки появляются, это, собственно говоря, является поводом, чтобы задуматься над внедрением IdM.
    У вас полный порядок, но много действий делается руками. IdM поможет это автоматизировать. Чем больше вендоров корпоративных систем, тем больше «стыков» можно будет построить через IdM.
    У вас системы одного вендора (когда IdM просто не нужна, всё и так делается через одну учётку), либо есть IdM в том или ином виде. Я видел, например, что в одновендорных системах действует согласование заявок (да хоть по почте, если бизнес-процессы отлажены), и всё работает. Так что здесь всё просто.


    Каждому сотруднику компании соответствует пользователь IdM-системы, создаваемый на основании кадровых данных, получаемых из доверенной системы (например, HR-системы). Учетные записи в целевых информационных системах создаются только с помощью IdM-системы и привязываются к конкретному сотруднику. Таким образом, любой учетной записи в информационной системе всегда соответствует её владелец — сотрудник компании

    Надо сказать, что внедрение IdM в сложной мультивендорной среде с множеством разных систем и ещё географически разделёнными подразделениями — задача нетривиальная. И сложная для руководства. Обычно действует принцип — «не трогай, пока работает», поэтому надо думать о таких вещах либо заранее, когда ещё легко внедрить систему, либо искать доводы. И вот здесь вашими лучшими друзьями становятся безопасники. Потому что они-то уж точно знают, чего может стоить всего одна учётка. И более того, наверняка у них есть примеры весьма неприятных ситуаций для компании, повторения которых они бы о-очень не хотели. И вы можете им помочь.

    Как система выдаёт права?

    Есть два способа: на основе правил, настраиваемых в системе (например, всем сотрудникам безопасности — доступны такие-то ресурсы, всем руководителям подразделений — такие-то и так далее). И по заявкам. Например, кто-то из закупки хочет больше данных о товаре и ему нужно получить доступ в 1С. Он отправляет заявку, система отслеживает иерархию, отправляет её, например, финдиректору. Если он подтверждает заявку, человек получает доступ.

    Как идёт внедрение

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

    В этап обследования обязательно включается аудит — проверка технической инфраструктуры. Речь идёт о том, что одна система может хранить идентификационные данные, например, в базе данных, другая система – в плоском файле. Ещё мы обследуем интерфейсы, по которым эти системы могут общаться в будущем с IdM (интерфейс и протоколы) для того, чтобы понять возможность вообще и трудоёмкость интеграции.

    Тут, главное, без излишнего фанатизма. Знаете, как бывает — «потратил 5 часов на написание алгоритма, который решает за 5 секунд задачу, которую я считал бы вручную 3 часа». Так вот, есть системы, которые не надо полностью интегрировать. Например, в компании тысяча сотрудников и в одной из систем работает только 50 человек. И это один отдел, и текучка этого отдела очень небольшая. Возможно, есть экономическая необходимость не интегрировать эту систему с IBT-менеджером, а скрестить её с IdM в ручном режиме. То есть, администратору этой системы будет при необходимости отправляться письмо с просьбой выдать права доступа тому или иному сотруднику. Такие варианты тоже возможны. У нас, в частности, был пример в компании на 10 тысяч человек, когда кадровая система, в которой работает 5 человек, имела технические ограничения, и мы предложили заказчику рассмотреть именно такой вариант. В итоге так и сделали.

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

    Чтобы пользователи работали по привычным схемам, большая часть событий может дублироваться в почту. Как подтверждал раньше финдиректор доступ письмом, так и может продолжать — только теперь письмо ему пишет робот из IdM и просит просто кликнуть по ссылке «да» или «нет».

    Счастье безопасников

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

    Параллельно появляется вторая часть математической задачи — расчёт оптимальных прав. Да-да, мы делаем некоторый Data Mining (хотя, громковато сказано для большей части случаев). И показываем, как можно оптимально разделять права. Выявляются какие-то вещи, которые не должны быть в нормальной структуре, которые могут привести к повышению рисков, связанных именно с доступом.

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

    Очень радует удобство обновления прав. Системы IdM умеют следить за ситуациями, когда права выданы, но человеку уже не нужны. Например, по должности сотрудник не выполняет работу, требующую доступа к финансовым отчётам компании, а такой доступ у него имеется. Система может обнаружить эту закономерность и выдать рекомендацию эти права убрать.

    Счастье пользователей

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

    Счастье IT-отдела

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

    Да, вы правильно поняли, что IdM очень бережёт нервы. Дело в том, что заявки на доступ отправляются уже не системному администратору, а тому, кто должен такой доступ подтверждать. Руководителю подразделения, финансовому директору, безопасникам — в общем, тем, кто прямо отвечает за вопрос. И это значит, что если раньше, когда что-то было не так, был виноват админ, то сейчас чётко понятно, кто, что и кому дал. А админ только обеспечил протокол.

    Бухгалтерия тоже счастлива

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

    Идеология

    В США и Европе такие системы уже давно, и к ним многие привыкли. Было бы странно, если бы в нашей стране не было особенностей менталитета, связанных с правами доступа. Главная проблема — доверенность источников. Например, кадровики много где просто обожают заносить все данные задним числом в систему, уже при увольнении. Это профессиональный сдвиг, ведь рабочая книжка заполняется по факту именно в этот момент.

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

    Деньги

    Лицензии дорогие. Условий множество, но обычно получается от десятков до нескольких сотен долларов на сотрудника. Впрямую, за счёт сэкономленного времени, системы окупаются за 3-4 года, но обычно идёт всё-таки по выгодам безопасников и прозрачной отчётности. Ещё особенность — когда компания проходит аудит, например, перед продажей (слиянием) или сертификацией, такие системы воспринимаются очень позитивно.

    Эволюция

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

    P.S. Если у вас есть вопросы по конкретной конфигурации для вашего случая или вы не можете задать вопрос в комментариях, пишите прямо мне на AZaikin@croc.ru.

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Язык до Кембриджа доведёт, или Как я перестал волноваться и полюбил W3C

    Посвящается Чарльзу, sine qua non.


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

    Сегодня я расскажу тебе, %username%, именно такую детективную историю. И завязкой в этой истории будет внезапное возникновение вот здесь, под номером 5, одной подозрительно русской фамилии:

    www.w3.org/2001/tag/

    История эта начинается в дождливом марте 2013 года, когда я узнал, что рабочая группа W3C Pointer Events собирает последние комментарии к своей спецификации. (Честно говоря, я совершенно не помню, какая была погода в марте, но мне почему-то хочется, чтобы она была дождливой.)



    Дело в том, что за полгода до того мы убили на реализацию работы с pointer-событиями в IE10 какое-то несоразмерное количество времени. Я бы даже сказал, какое-то абсурдно несоразмерное количество времени. Сложность реализации этого функционала оказалась гораздо больше оценочной вследствие (а) непродуманности и сырости самого стандарта, (б) наличия кучи тонких и не описанных в документации моментов, (в) существенной разницы в реализации на разных платформах (Win 7 / Win 8).

    Да, забыл сказать, «мы» — это, в данном случае, команда API Яндекс.Карт, которую я имею честь возглавлять. Мы в API традиционно уделяем существенное время поддержке разного рода мобильных/тач браузеров, но IE10 превзошел все мыслимые ожидания. Думаю, не сильно покривлю душой, если скажу, что на IE10/IEMobile мы убили больше времени, чем на все остальные мобильные браузеры вместе взятые.

    И вот, в конце марта наш консультант по веб-стандартам Чарльз МакКети Невилл aka chaals рассказал, что W3C собирает последние замечания по проекту стандарта Pointer Events, и поинтересовался, есть ли у кого-то комментарии. (Note: если ты ничего не понял из этого предложения, %username%, см. большое интервью Чарльза о том, как работает W3C.)

    Я почитал эту спецификацию; как ни удивительно, она представляла собой точную кальку уже реализованного в IE10 функционала, только что без префикса «MS». «Давно я не брал в руки шашку», — подумал я, и сел писать замечания.

    За перипетиям этой замечательной переписки вы можете пронаблюдать в официальной рассылке группы Pointer Events, начиная вот с этого письма: lists.w3.org/Archives/Public/public-pointer-events/2013JanMar/0184.html и далее по ссылкам. Исходное письмо написал Чарльз, а вот последующие письма от Sergey Konstantinov — это мои.

    Упс, я, кажется, невольно раскрыл своё инкогнито. Впрочем, по итогам всей той истории, что я вам рассказываю, я стал существенно более публичным человеком, чем хотел бы; так что, кажется, пришло время немножко развиртуализироваться и на Хабре. Меня зовут Сергей Константинов, я возглавляю группу разработки API Яндекс.Карт (в Яндексе, как подсказывает нам кэп), а с недавних пор ещё и участвую в деятельности W3C Technical Architecture Group (aka TAG). Но до этого мы ещё дойдём.

    У меня, кстати, есть виртуал на Хабре — SergeyKonstantinov — которого я заводил, чтобы постить официальные статьи и новости. Надолго меня не хватило — не моё это :) Поэтому не стоит воспринимать меня как какого-то официального представителя Яндекса на Хабре. Я здесь занимаюсь тем, чем мне нравится; в основном — троллю и набрасываю, местами довольно эпично. Кстати, пользуясь случаем, хотел бы передать отдельный привет тем, кто минусовал этот комментарий.

    Так вот, вернёмся к нашим баранам. Пересказывать здесь длительную и бесплодную переписку с Pointer Events WG я не буду; все ответы на мои замечания выглядели примерно так: либо «хороший пойнт, обязательно запилим во второй версии спецификации», либо «а наши эксперты говорят, что так ок». (Например, вопрос: а как мне отменять реакцию на события браузера через одну часть канваса, а через другую — пропускать? Ответ: заведи два канваса, чо как маленький.) В итоге мне удалось добиться ровно одного: из спецификации убрали требование событиям мыши иметь id = 1. (Что, как вы понимаете, не потребовало внесения никаких изменений в код IE.)

    Я бросил эту бесполезную переписку примерно через три недели, когда понял, что (а) никто ничего не будет менять, (б) а если и поменяет, то хуже от этого будет исключительно нам, т.к. нам придётся переписать весь код под IE. Ну и до кучи мне уже начали там немного хамить в стиле «what's wrong with you, man?»



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

    TAG (Technical Architecture Group) — это особая группа в W3C, основной задачей которой является координация всех остальных рабочих групп, решение кросс-стандартных вопросов и — самое главное! — единого архитектурного подхода к веб-стандартам. Подробнее об этом можно почитать в TAG Charter. TAG состоит из 9 участников и председателя, которым является Тим Бёрнерс-Ли. Троих участников назначает председатель, а ещё шестерых избирает W3C Advisory Committee.

    В мае один из шести избранных участников досрочно покинул TAG, т.к. перешёл работать в Mozilla, а правила TAG запрещают одной компании делегировать более одного участника в TAG. Таким образом, были объявлены досрочные выборы, и мы (Яндекс) решили принять в них участие.

    Признаться честно, ввязываясь во всю эту авантюру, я не очень-то рассчитывал на успех. Я написал несколько «предвыборных» постов, доступных в моём tumblr-блоге: konstantinov.cc/, в которых (довольно мягко) покритиковал невнимание рабочих групп к внешнему фидбеку и общую фрагментированность архитектурных принципов в разных рабочих группах. Кроме того, я написал большой пост о том, как, по моему мнению, следует разрабатывать API. (Спойлер: приходите на YaC, там будет часовой доклад от нашей команды про архитектуру API.)

    И вот, 18 июля я вдруг обнаружил в почте письмо от Дэниэла Эппелквиста, со-председателя TAG, с поздравлением и курсом молодого бойца. Признаться, я до сих пор пребываю в некотором шоке, хотя прошел уже месяц, я успел поучаствовать в трёх телеконференциях, одном ревью и сделать первый коммит в гитхаб w3ctag.

    У TAG нет каких-то особенных формальных обязанностей; каждый её участник, в основном, сам определяет направления своей деятельности. Я же, как и обещал, вызвался проводить ревью новых спецификаций и разрабатывать API Design Guide, чем и пытаюсь заниматься в меру своих скромных сил.



    На этом, кажется, почти детективная история появления моей фамилии в списке W3C TAG закончена. Stay tuned.

    P.S. Большая просьба к комментаторам не изгаляться в петросянстве. Меня уже попросили сделать нормальное событие change в инпутах и запретить поддомены www. TAG этим не занимается, не надо писать тут безумных предложений; я интеллигентный человек, могу и матернуть.

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

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    Наглядно о том, почему я не беру кредиты

    Кредит — это когда банк вас грабит и вы ему за это ещё платите.
    Пожарный Сидоров бездействовал: банк горел — кредит гасился.


    Привет, Хабр!

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

    Постановка задачи
    Программист Вася имеет стабильную работу и зарплату. Всё это время он вёл беззаботную жизнь, и не думал о накоплениях, но недавно Вася женился, и стал задумываться о собственном жилье. Подумал он, и решил, что может стабильно откладывать B руб. в месяц. Сейчас квартира стоит S руб. В стране стабильная инфляция H %. Проценты по вкладу — F %, а по кредиту G %. Вклад с капитализацией раз в месяц.
    Персонажи вымышлены, все совпадения случайны.

    Найти
    Как лучше поступить Васе — откладывать деньги в банк или взять кредит? Насколько выгоднее?

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

    Решение
    Так как у Васи фиксированная сумма пополнений, то мы можем рассмотреть выгодность того или иного способа приобретения жилья, найдя количество месяцев, которые ему придётся выделять эту сумму, до полной выплаты суммы жилья.

    Подробное решениеПусть:
    n — это количество месяцев, за которые Вася накопит на жильё.
    m — это количество месяцев, которые Вася будет выплачивать кредит.
    Тогда из отношения m/n мы сможем судить о выгодности, того или иного способа в m/n раз.

    Введём коэффициенты:
    f = 1 + F/(100*12)
    g = 1 — G/(100*12)
    h = 1 + H/(100*12)
    это ежемесячные коэффициенты преумножения/потери суммы вклада/ценности/стоимости.

    Рассмотрим, как будет изменяться сумма вклада в конце каждый месяца:


    Используя формулу:

    найдём, что сумма в конце срока будет равна:


    Но за n-месяцев квартира успела подорожать за счёт инфляции. Найдём её стоимость:


    Итого:


    В случае кредита, формулы будут аналогичны, с той лишь разницей, что деньги теряют стоимость, и процент по кредиту это компенсирует:


    Из двух выше описанных формул, выведем, что:


    Таким образом, мы вывели общую формулу выгодности вклада/кредита в зависимости от их сроков:


    Пример 1 — либеральный
    Я взял следующие реальные цифры в качестве примера:
    Процент по вкладу: F = 10% годовых.
    Процент по кредиту: G = 12.5% годовых.
    Уровень инфляции: H = 8.7% годовых (взял как среднее за 2008-2012)
    Вася может позволить себе выделить B = 40000 руб./мес.
    Вася очень хочет купить квартиру стоимостью S = 2 733 000 руб.
    В итоге получился такой вот график (спасибо сервису yotx.ru):


    Как видно, логично, что чем меньше срок вклада/кредита, тем меньше между ними разница. Кроме того у графика есть асимптота, при значении n=140. Это говорит о том, что никакими способами нельзя выплатить кредит на ту же сумму, таким же размером ежемесячного платежа, как если бы Вася откладывал на вклад. То есть это предел кредитования, и следовательно нужную сумму Вася может накопить только вкладом.

    Например, если Вася возьмёт кредит 2 733 000 руб. на 10 лет (120 мес.), то ему нужно будет выплачивать как раз по 40 000 руб. Банковским вкладом, он накопит нужную сумму с учётом инфляции (5 160 834 руб.) за 88 месяцев. Итого 120/88 = 1.36, что сходится с графиком.
    Взять кредит сумму, более чем 3 833 000 руб. (эта цена через 140 мес. превратится в 10 538 000 руб. за счёт инфляции, именно эта сумма будет на счёте к тому времени) Вася позволить себе не сможет, т. к. при том же размере ежемесячных выплат выплатить кредит невозможно, как бы он не растягивал срок.

    Пример 2 — экзотический
    Рассмотрим тот же пример, но поменяем лишь размер инфляции:
    Уровень инфляции: H = 11% годовых
    Стоит отметить, что данный вариант маловероятен, т. к. обычно процентная ставка по вкладам всегда выше уровня инфляции. Хотя и не всегда.

    Получаем график:


    Тут получается интересная ситуация, когда вклад выгоден только на промежутке ~58-97 месяцев, во всех остальных случаях брать кредит выгоднее.
    Например, Вася возьмёт те же 2 733 000 руб. в кредит. Банковским вкладом, он накопит нужную сумму с учётом инфляции (8 169 345 руб.) практически за те же 120 месяцев.

    Пример 3 — грабительский
    Рассмотрим другой реалистичный пример, современный потребительский кредит. Данные как в примере 1, но поменяем процентную ставку по кредиту:
    Процент по вкладу: F = 10% годовых.
    Процент по кредиту: G = 20% годовых.
    Уровень инфляции: H = 8.7% годовых.



    Как видим, Васе тут уже тяжелее, т. к. кредит на таких условиях больше чем на 6 лет брать ему становится очень затратно, по сравнению с вкладом. А предел кредитования для Васи гораздо меньше — 2 400 000, то есть желаемую квартиру Васе уже не купить в кредит, даже за 50 лет

    Заключение
    Так всё же, стоит ли брать кредиты? Решать, конечно же, вам. У кредитов есть, преимущество — вы получаете желаемое уже сейчас, следовательно, вы можете уже пользоваться вашей новенькой квартирой, а не ждать 10 лет, поэтому даже 1,5x-2x переплата в этом случае не так страшна, особенно если приходится платить аренду за чужую квартиру всё это время. С другой стороны, в нашей жизни нет никаких гарантий, что условия задачи будут стабильными как в примерах, и тут главное не выйти за асимптоту, иначе кредит будет попросту непосильной ношей.

    Ну и напоследок опрос по теме.


    Какими банковскими услугами вы пользуетесь больше


    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста. Проголосовало 1204 человека. Воздержалось 264 человека. Источник: habrahabr.ru,
    получено с помощью rss-farm.ru




    В основном вклады



    И тем и другим



    В основном кредиты



    Инвестирую/получаю средства другими способами



    Не пользуюсь банками (занимаю у друзей/храню в стеклянной банке)

    RailsClub'Moscow 2013 – 28 сентября в Москве. Конференция ruby / ruby on rails разработчиков



    RailsClub’Moscow 2013

    28 сентября 2013 в Москве на территории центра Digital October состоится 12-ая конференция веб-разработчиков на языке Ruby и фреймворке Ruby On Rails – RailsClub’Moscow 2013.

    RailsClub’Moscow 2013 соберет вместе ведущих российских и известных иностранных Ruby разработчиков, которые поделятся с участниками конференции своими знаниями и опытом.

    На RailsClub 2013 будем обсуждать проектирование, разработку, тестирование, отладку, оптимизацию под большие нагрузки, масштабирование и эксплуатацию ruby on rails проектов.

    Докладчики
    В этом году в качестве докладчиков к нам приедут знаменитые ruby звезды:

    • Obie Fernandez (США), автор серии книг “The Rails Way”, основатель Hashrocket
    • Linda Liukas (США), обладатель Ruby Hero Award 2013, автор книги “Hello Ruby” и активистка RailsGirls
    • Ernie Miller (США), автор Squeel, докладчик на RailsConf 2013
    • Frederick Cheung (Англия), обладатель Ruby Hero Award 2012
    • Eric Hodel (США), обладатель Ruby Hero Award 2012
    • Jeremy Evans (США), ведущий разработчик Sequel

    Выступления иностранных спикеров будут синхронно переводиться на русский язык. Полный список спикеров, детали программы, в том числе ее неофициальной части, будут объявлены в ближайшее время на официальном сайте конференции — http://railsclub.ru

    Конференция RailsClub 2013 — это уникальный шанс получить новые знания, пообщаться с друзьями, коллегами и звездами Ruby в комфортной обстановке Digital October.

    Спонсоры
    Мы рады объявить о том, что генеральным спонсором нашей конференции стала компания undev.ru



    Undev.ru – сильная команда разработчиков на Ruby, Objective C, C++, C#, JavaScript. Работают над созданием уникальной технологической платформы для телевизионного вещания через интернет. На базе этой платформы были сделаны такие крупные проекты, как Веб-выборы 2012, ПМЭФ, трансляция ванкуверской и лондонской олимпиад, и еще несколько проектов аналогичного масштаба.

    Благодарим наших спонсоров за оказанную поддержку!

    Организаторы
    Evrone.ru и Express42.com

    Регистрация
    Регистрация и оплата участия в конференции — railsclub.timepad.ru/event/76008/?utm_refcode=95c73ccecc305e313977a72d1c6f02260353ae99

    Первые 50 зарегистрировавшихся участников получат билеты по специальной цене — 5000 рублей.

    Будьте в курсе наших новостей, подписавшись на рассылку на сайте railsclub.ru, и следите за обновлениями:

    Сайт конференции: railsclub.ru
    Страница на facebook: www.facebook.com/railsclub
    Twitter: http://twitter.com/#!/railsclub_ru

    Вопросы, предложения, пожелания: Олег Балбеков, oleg@railsclub.ru, 8 (926) 7545323

    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    [Перевод] Наука под замком. Вторая часть



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




    Некого винить, кроме себя
    Критики монополии частных издателей предлагают простое решение — журналы с открытым доступом. Так же, как и обычные журналы, они принимают статьи, организовывают процесс рецензирования и публикуют их. Но они не требуют денег за подписку — все статьи свободно доступны онлайн. Чтобы покрыть расходы, они берут с учёных, желающих публиковаться небольшой гонорар (в среднем около 2000 долларов). Рецензенты, которые решают, какие статьи стоит публиковать, не получают денег от журналов, чтобы избежать соблазна принимать всё подряд. В отличие от традиционных журналов, которые требуют исключительных авторских прав в на возможность публиковаться, журналы с открытым доступом практически свободны от копирайтных ограничений.

    Если университеты финансируют исследования, и их сотрудники как пишут, так и рецензируют статьи, то почему же они все до сих пор не переключились на журналы с открытым доступом? Успешных примеров таких открытых проектов как Public Library of Science пока очень немного. Всё дело в том, что сложившаяся научная культура делает такой переход очень трудным.

    История публикаций в престижных журналах — необходимое условие продвижения по научной карьерной лестнице. Каждая статья, опубликованная в молодом и ещё не ставшим авторитетным журнале с открытым доступом, могла бы быть опубликована в таких флагманах рынка, как Science или Nature. И если ещё можно представить себе уже занимающего хорошую должность профессора-идеалиста, который готов пожертвовать частью своего престижа ради науки, то как насчёт его молодых соавторов, для которых статья в авторитетном журнале может значить всё?

    Изменить этот статус кво могли бы правительства, заставляя предоставлять открытый доступ ко всем исследованиям, проведённым за государственный счет. В США ежегодно в виде грантов на научные исследования государство выделяет 60 миллиардов долларов. В 2008 году конгресс, преодолев яростное сопротивление издателей, обязал их давать свободный доступ ко всем статьям, основанным на исследованиях, проведённых Национальным институтом здоровья (на который приходится половина всего государственного финансирования науки) через год после первой публикации. Распространение такой практики на все остальные отрасли науки могло бы дать сильный толчок развитию журналов с открытым доступом. Подобные меры сейчас рассматривают правительства Великобритании и Канады.

    Издержки закрытой публикации: статья Рейнхард-Рогоффа

    Дискуссия вокруг статьи 2010 года «Рост во время задолженности», опубликованной гарвардскими экономистами Кармен Рейнхард и Кеннетом Рогоффом в журнале American Economic Review, демонстрирует некоторые проблемы системы научных журналов.

    На основании данных по росту ВВП и уровню государственного долга разных стран, авторы статьи пришли к выводу, что рост ВВП оказывается существенно медленнее в странах, где уровень задолженности превышает 90% от ВВП.

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

    Но в апреле этого года группа учёных из Массачусетского университета в Амхерсте нашла ошибку в статье Рейнхард-Рогоффа. Как и многие другие экономисты, учёные безуспешно пытались воспроизвести результаты Рейнхард и Рогоффа. И только когда гарвардские коллеги выслали им исходные данные в таблицах Excel, в Массачусетсе поняли, почему ни у кого не удавалось воспроизвести эти результаты. Ошибка в формуле. Пять ячеек данных не вошли в диапазон. Без этой ошибки и некоторых спорных моментов использовавшейся методики взвешивания результатов эффект Рейнхард-Рогоффа не наблюдался. Вместо уменьшения на 0,1%, страны с долгом выше 90% показывали рост ВВП на вполне приличные 2,2%.



    Ошибка была найдена, но в течение двух лет на статью ссылались многие влиятельные политики и экономисты.

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

    Система журналов сильно замедляет публикацию результатов исследований. Рецензирование очень редко проходит быстрее, чем за месяц, и журналы часто просят авторов переписать часть статьи или провести дополнительные изыскания. В результате время до публикации статьи растягивается на полгода и больше. Хотя контроль качества необходим, благодаря гибкости интернета статьи теперь вовсе не обязательно приводить в полностью завершённый вид до публикации. Майкл Айзен, сооснователь Public Library of Science, говорит, что согласно его опыту «большинство серьёзных недостатков обнаруживаются только после того, как статья опубликована».

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

    Но журналы не могут поддерживать свой престиж, публикуя отчёты о провалившихся экспериментах.
    Из-за этого научное сообщество лишено ценной информации о неподтвердившихся гипотезах. Более того, это толкает учёных на подгонку результатов и излишне оптимистичные выводы, которые не опираются на достоверные данные, и в которых даже сам автор не уверен. Пока наука не перерастёт современную журнальную систему, мы не узнаем, сколько ложных «открытий» сделано из-за желания показать хоть какой-то результат.

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

    Собирая информацию о научных журналах и организации научной работы вообще, мы побеседовали с представителями Banyan, стартапа, чья миссия — способствовать открытости в науке. Нас поразило, насколько много вещей можно сделать уже сейчас, без каких-либо революционных прорывов в технике. «Мы нацелились на процесс рецензирования — сказал нам CEO Banyan Тони Жмайель — куча народу всё ещё распечатывают свои статьи и физически пересылает их рецензентам или отправляют их по почте в формате .doc».

    Banyan недавно запустил публичную бета-версию своего продукта, который позволяет делиться, сотрудничать и публиковать результаты научной работы. «В основе нашей компании — объясняет Тони — лежит уверенность, что учёные перейдут на рельсы Open Source, если им дать простые и удобные инструменты».

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

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

    Рассказывает он и об инструментах, которых ещё не существует. Например, система взаимосвязанных вики, которая позволила бы учёным создавать и поддерживать самые полные и актуальные "суперучебники" в их областях исследований, которые все их коллеги могли бы использовать как справочники. Или эффективная система взаимопомощи учёных разных специальностей, на случай, когда исследования заводят на «чужую территорию» (даже Эйнштейн разработал Общую теорию относительности не самостоятельно, ему потребовалась помощь математиков). Полный список его предложений можно увидеть в замечательной статье "Будущее науки".



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

    Говоря об этой проблеме, Тони приводит в пример дух открытости, который царит в мире разработки свободного ПО. «В науке сейчас нет никакой системы вознаграждений за открытость. На ней не сделаешь карьеры. А вот в программировании каждый захочет взглянуть на ваш аккаунт на Гитхабе».

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

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

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

    Майкл Нильсен
    .
    Существующая схема государственного финансирования исследований и последующей публикации их результатов в научных журналах сложилась во времена Исаака Ньютона и успешно решала проблемы науки XVII века.

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

    Разрушительный эффект от этого «не поддаётся никаким измерениям и оценкам, — утверждает Тони Жмайель — мы не знаем, какие открытия могли бы быть совершены и какие проблемы могли бы быть решены, если бы знания не оказались заперты за высокими финансовыми заборами. Представьте себе, что было бы, если бы Тим Бернерс-Ли не выложил бы свои разработки Всемирной паутины в открытый доступ, или запатентовал их?»

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

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




    P.S. Сегодня на Хабре был опубликован ещё один перевод, раскрывающий тему конфликта между учёными и издательствами: "Эльзевир — мой вклад в его ". Не пропустите!


    Источник: habrahabr.ru,
    получено с помощью rss-farm.ru


    ZBase32, Base32 и Base64 алгоритмы кодирования

    Привет!

    Многие используют Base64 кодирование, реже Base32 и еще реже ZBase32 (вы знаете о таком?), но не все понимают их алгоритмы. В статье я описываю достоинства, недостатки данных кодировок, а также рассказываю о их реализации.

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

    Учитывая указанные требования в качестве алгоритма было выбрано ZBase32-кодирование.
    Как оказалось, стандартной реализации в .net нет (в отличие от base64), поэтому пришлось писать самому. К своему удивлению, я столкнулся с трудностями при поиске внятного объяснения Base32 и ZBase32. Были найдены какие-то готовые решения, но я не мог, не разобравшись в алгоритме применять их, а читать магию больших формул, битовых сдвигов было тяжело без словесного описания. Теперь, когда для меня все позади, я хотел бы поделиться с вами небольшим знанием элементарного кодирования. Статья носит академический характер.

    Плюсы и минусы

    Base64
    Позволяет кодировать информацию, представленную набором байт, используя всего 64 символа: A-Z, a-z, 0-9, /, +. В конце кодированной последовательности может содержаться несколько спецсимволов (обычно “=”).

    Преимущества:
    • Позволяет представить последовательность любых байт в печатных символах.
    • В сравнении с другими Base-кодировками дает результат, который составляет только 130% от длины исходных данных.
    Недостатки:
    • Регистрозависимая кодировка.
    Base32
    Использует только 32 символа: A-Z (или a-z), 2-7. Может содержать в конце кодированной последовательности несколько спецсимволов (по аналогии с base64).

    Преимущества:
    • Последовательность любых байт переводит в печатные символы.
    • Регистронезависимая кодировка.
    • Не используются цифры, слишком похожие на буквы (например, 0 похож на О, 1 на l).
    Недостатки:
    • Кодированные данные составляют 160% от исходных.
    ZBase32
    Кодировка аналогична Base32, но имеет следующие отличия.
    • Человеко-ориентированный алфавит из 32 символов. Наиболее проработанная таблица символов для облегчения написания, произношения и запоминания кодированной информации. Авторы переставили наиболее удобные для человека символы на позиции, которые используются чаще всего. Как они это сделали я не знаю. Алфавит приводится ниже.
    • Нет специальных символов в конце результата кодирования.
    Подробнее про каждую из кодировок можно почитать в Википедии здесь и здесь, а сейчас я хотел бы остановиться непосредственно на реализации ZBase32.

    Описание алгоритма ZBase32 кодирования

    Позволю себе при описании алгоритма показывать выкладки на C# для большего понимания.

    Итак, имеем 32-х символьный алфавит следующего содержания:
    <code class="cs">static string EncodingTable = "ybndrfg8ejkmcpqxot1uwisza345h769";
    </code>
    На входе массив байтов (естественно, по 8 бит каждый), который хотелось бы перевести в символы из алфавита.
    <code class="cs">public static string Encode(byte[] data)
    {
    </code>
    Алфавит представляет собой строку из 32-х элементов, а это означает, что каждый из его символов кодируется числом от 0 до 31 (индексы символов в строке). Как известно, любое число от 0 до 31 в бинарной системе счисления можно записать, используя 5 битов байта. Из этого следует, что если представить исходный набор байтов как единый массив битов и разбить его на кусочки по 5 битов (см. рисунок ниже), то мы получим набор координат символов из алфавита. Вот, собственно, и все.

    Алгоритмы Base32 и Base64 аналогичны ZBase32, только разные алфавиты (по составу в случае с Base32, по составу и размеру в случае Base64) и размеру “отщипываемых” кусочков бит (6 бит для Base64).



    Итак, я предлагаю перед тем, как начать разбиение исходных данных на кусочки по 5 бит, подготовить место куда будет записываться результат. Чтобы не задумываться об индексах в статических массивах, давайте использовать StringBuilder.
    <code class="cs">var encodedResult = new StringBuilder((int)Math.Ceiling(data.Length * 8.0 / 5.0));
    </code>
    При инициализации сразу задаем размер результирующей строки (чтобы не тратить время на расширение в процессе работы алгоритма).

    Теперь осталось пробежать по исходному массиву байтов и разделить его на 5-и битовые кусочки. Для удобства я предлагаю работать с группой по 5 байт, так как это 40 бит — число, кратное длине “кусочков”. Но не забываем, что исходные данные никто для нас не подгонял, поэтому учитываем возможность недостачи.
    <code class="cs">for (var i = 0; i < data.Length; i += 5)
    {
         var byteCount = Math.Min(5, data.Length - i);
    </code>
    Так как мы работаем с группой из 5 байт, нам нужен буфер, где будет формироваться сплошной набор битов (всего 40 бит). Заведем переменную типа ulong (64 бита в нашем распоряжении) и поместим туда текущую партию байтов.
    <code class="cs">ulong buffer = 0;
    for (var j = 0; j < byteCount; ++j)
    {
          buffer = (buffer << 8) | data[i + j];
    }
    </code>
    И заключительный этап — это “отщипывание” из того, что получилось, кусочков по 5 бит и формирование результата.
    <code class="cs">var bitCount = byteCount * 8;
    while (bitCount > 0)
    {                    
          var index = bitCount >= 5
                              ? (int)(buffer >> (bitCount - 5)) & 0x1f
                               : (int)(buffer & (ulong)(0x1f >> (5 - bitCount))) << (5 - bitCount);
    
          encodedResult.Append(EncodingTable[index]);
          bitCount -= 5;
    }
    </code>

    Возможно, в последнем примере кода с первого взгляда не все понятно, но если вы немного сосредоточитесь, то все станет на свои места.

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

    Вы можете посмотреть полную реализацию ZBase32Encoder.

    Заключение

    И, конечно, в заключение хочется сказать следующее.
    <code class="cs">4nq7bcgosuemmwcq4gy7ddbcrdeadwcn4napdysttuea6egosmembwfhrdemdwcm4n77bcby4n97bxsozzea9wcn4n67bcby4nhnbwf94n9pbq6oszemxwf74nanhegow8em9wfo4gy7bqgos8emhegos9emyegosmem5wfa4n6pbcgozzemtwfirr
    </code>