"Абсолютно случайным образом ударяя по
клавишам пишущей машинки, гипотетическая
обезьяна рано или поздно напечатает одну
из пьес Шекспира."
|
Thursday, 14 May 2015
Линейность математического ожидания или Typewriter Monkey
Tags:
algorithms,
dynamic programming,
expected value,
Google Code Jam,
linearity,
Typewriter Monkey
Вы знаете что такое математическое ожидание? Тогда сегодня я вам предлагаю поразмыслить над следующей задачкой по программированию Typewriter Monkey.
На прошлых выходных я участвовал в конкурсе Google Code Jam и единственная задача, которая не далась мне полностью оказалась задача про обезьян с печатными машинками.
Итак, для начала, вкратце об условиях конкурса. Условия задачи описаны в тексте по ссылке выше. Решать задачу можно на абсолютно любом языке программирования. На странице с заданием можно скачать два тестовых набора данных: маленький и большой. Данные в обоих случаях структурированы одинаково, отличие в ограничениях на начальные условия и количество времени, которое можно потратить на генерирование ответа.
В нашем случае ограничения следующие:
Friday, 8 February 2013
Regular Expressions basics course
И снова регулярные выражения. Как я говорил, многие почему-то боятся использовать регулярные выражения в повседневной жизни технического специалиста. Есть даже известная фраза:
"Иногда люди сталкиваются с проблемой и думают: "Для решения я использую Регулярные Выражения". Теперь у них две проблемы." (c) история появления фразы
Ключ к решению задач и преодолению страха перед формальными языками (коим является RegExp) – обучение, не так ли? И сегодня я хотел бы поделиться с Вами своим курсом по основам регулярных выражений. 20 кратких слайдов, которые могут изменить (я надеюсь) Ваш подход к поиску информации. Вы не представляете сколько Вы теряете не пользуясь регулярками. Их поддержка встроена во все современные языки программирования, во многие утилиты и консольные приложения. И по сути, если где либо Вы встречаете слово шаблон или маска, то в половине случаев это будет регулярное выражение.
Интересно? Ай-да под кат.
index
"Иногда люди сталкиваются с проблемой и думают: "Для решения я использую Регулярные Выражения". Теперь у них две проблемы." (c) история появления фразы
Ключ к решению задач и преодолению страха перед формальными языками (коим является RegExp) – обучение, не так ли? И сегодня я хотел бы поделиться с Вами своим курсом по основам регулярных выражений. 20 кратких слайдов, которые могут изменить (я надеюсь) Ваш подход к поиску информации. Вы не представляете сколько Вы теряете не пользуясь регулярками. Их поддержка встроена во все современные языки программирования, во многие утилиты и консольные приложения. И по сути, если где либо Вы встречаете слово шаблон или маска, то в половине случаев это будет регулярное выражение.
Интересно? Ай-да под кат.
Regular Expression quiz
Понравился Regular Expression Crossword из предыдущей записи? У меня для Вас хорошая новость – некоторое время назад я составил небольшой опрос-викторину, когда готовил курс по изучению регулярных выражений.
Регулярные выражения вообще говоря очень интересная тема. Дело в том, что они нас окружают практически везде, поддержка есть во всех языках программирования, но многие разработчики почему-то страшно оттягивают момент познания. Прямо какая-то фобия регулярок.
Итак, считаете себя несокрушимым ниндзя-экспертом Регулярок? Не уверены, но хотели бы попробовать свои силы? Новичёк, но не знаете с чего начать обучение? Для Вас ниже всего дестяь (10) усложняющихся вопросов на знание различных тем регулярных выражений.
index
Регулярные выражения вообще говоря очень интересная тема. Дело в том, что они нас окружают практически везде, поддержка есть во всех языках программирования, но многие разработчики почему-то страшно оттягивают момент познания. Прямо какая-то фобия регулярок.
Итак, считаете себя несокрушимым ниндзя-экспертом Регулярок? Не уверены, но хотели бы попробовать свои силы? Новичёк, но не знаете с чего начать обучение? Для Вас ниже всего дестяь (10) усложняющихся вопросов на знание различных тем регулярных выражений.
Thursday, 7 February 2013
Regular Crossword
Tags:
algorithms,
crossword,
quiz,
regex,
regular expression
Regular expressions crossword |
Любите головоломки? Знаете регулярные выражения? Тогда время Че настало... Я не пожалел потраченного времени на решение.
Итак, у нас есть соты. В каждой ячейке должна стоять буква латинского алфавита. Каждое регулярное выражение должно полностью "матчить" свою строку. Таким образом каждая буква будет провалидирована тремя разными регулярками.
Для получения читабельного PDF – кликните на картинку.
Monday, 9 January 2012
Handmade lamp/alarm clock with Android charge
Tags:
Android,
DIY,
lamp alarm
Взбрело мне в голову поиграться с микросхемами. Поскольку от схемотехники я уже далёк, то решил сделать для начала что-то простое, но полезное, а затем уже двигаться к сложному и just-for-fun. Выписал список идей, составил таблицу истинности плюсов и минусов, отсортировал в порядке усложнения...
В итоге, решил сделать световой будильник с использованием Андроида. В чём суть?
Saturday, 24 September 2011
Influence, Robert Cialdini
Tags:
books,
Cialdini,
influence,
psychology
В последнее время я стал достаточно много читать и решил поделиться немного с вами. Очередную книгу по психологии мне посоветовал друг. Встречайте: Robert Cialdini, Influence.
Честно говоря, я люблю психологию в доступном изложении, но, к сожалению, к подобным книгам отношусь с опаской. Слишком громкое название, за которым автор обычно прячет достаточно известные принципы, которые разжевываются по триста раз и вода в тексте, в которой утопаешь, забыв о сути книги. Не совсем понимаю почему многократное повторение так любят авторы подобной литературы, но мне это не подходит. Именно по данной причине, например, я не могу читать Карнеги Дейла. Так что же мне понравилось в данной книге?
Sunday, 19 June 2011
Immigration process (search for a work)
Tags:
expat,
immigration,
work permit,
work search
"Люди думают, что будут счастливы, если переедут в Париж, а потом оказывается: куда бы ты ни поехал, ты берёшь с собой себя." (с)овершенно точно.
Сегодня мы поговорим о вопросах поиска работы за пределами родной страны. Данный пост по сути родился из моего опыта и всё учащающихся вопросах о процессе иммиграции. Хочется начать рассказ с самого начала: с поиска работы, ибо только подписанный контракт на сегодняшний день - залог долгосрочной визы. Речь, естественно об IT.
Данный пост почему-то захотелось оформить в стиле поучительного TO-DO списка. Итак, поехали:
0. Определись с тем, чего именно ты хочешь. Какова твоя цель, что ты за человек, где истоки твоего желание, чтобы не получилось как в эпиграфе.
1. Страна или страны. Этот выбор стоит сделать на достаточно раннем этапе.
1.1. Изучи иммиграционное законодательство целевой страны. Обычно достаточно изучить материалы на сайтах посольств или консульств. Там есть большинство документов и описанных процессов.
1.2. Узнай какие типы виз тебе подходят. В некоторых странах действуют программы для "Highly Skilled Immigrants", по которым тебе вообще не нужен рабочий контракт, для получения визы. Достаточно соответствовать некому набору критериев. (Большинство таких программ, к сожалению, закрылись или в процессе закрытия)
1.3. Изучи рынок. Узнай какие вакансии преимущественно попадают на IT рынок данной страны, какие у них зарплаты. Здесь сильно помогают monster.com и glassdoor.com
1.4. Изнай сколько налогов ты будешь платить, сколько стоит жилье, сколько тебе понадобится на еду (для начала умножай на два с тем расчетом, что ты будешь тратить больше пока не освоишься).
2. Вылижи резюме.
2.1. Резюме должно быть на английском, а не на его подобии.
2.2. Вот собственно: CV style. Мои взгляды особо не поменялись :)
2.3. Составь сопроводительное письмо. Небольшое, не раздражай читающего, но из которого станет понятно, что ты адекватный человек, ищешь работу и тебе нужна виза. Последний пункт очень важен: лучше не тратить времени зря и искать сразу тех, кто понимает, что на данный момент ты ВНЕ целевой страны.
2.4. Ну и наконец, используй PDF :) Хотя лучше иметь заготовки в разных форматах.
3. Параллельно можно начинать искать вакансии, но инфо из первого пункта стоит знать заранее, чтобы чувствовать себя более комфортно в разговоре.
3.1. Составь список компаний, которые работают в данной стране. Выписывай и крупные, и маленькие. Можно искать через тот же Monster например, но одного источника мало. Многие крупные компании вообще не работают через агенства - о их вакансиях можно узнать только у них на сайте.
3.2. Составь себе табличку, где будешь собирать данные о компаниях, их контакты и ссылки на вакансии, на которые ты выслал своё резюме. Стоит помнить куда именно ты отсылал письма и как называются вакансии (может сильно пригодится).
3.3. Будь готов, что если кто-то заинтересуется - будут звонить. Телефонный контакт для HR очень важен: он более надёжен + позволяет хоть немного оценить адекватность и наличие языка. Если можешь говорить только в определённое время - укажи это в резюме.
3.4. Писать надо всем. Неважно есть у компании открытая вакансия или нет. Не важно, что в вакансии указано, что требуются жители только определённой страны. Всякое бывает. Главное, ты не должен скрывать, что ты сам находишься вне этой определённой страны.
3.5. Если какая-то компания нравится больше всего, через день после отсылки резюме перезвони и уточни получили ли они твоё письмо.
4. Ну и BodyShop
4.1. Такие фирмы, как Епам, Люксофт и множество других перевозят людей. Они получают процент от твоей з/п в итоге. Этот вариант стоит рассматривать в самый последний момент, ибо условия работы зачастую пониже будут + есть свои нюансы. Из позитивных моментов - компания берёт на себя всё оформление.
5. Немного психологии.
5.1. Будь готов, что многие не отвечают вообще.
5.2. Пойми, что процесс может быть очень длительным.
5.3. Если кто-то пригласил на собеседование, это еще не победа. Иногда надо пройти 6-8 собеседований в одной и той же компании, чтобы устроится на работу.
P.S. Если кто-то не в курсе про источник картинки: Поросёнок Петя
Wednesday, 6 April 2011
PostgreSQL. Redirect data to child partition.
Tags:
db,
partitioning,
plpython,
postgres,
variable table name
На одном из недавно "вверенных" проектов жил поживал PostgreSQL с настроенным разбиением данных по таблицам-разделам в зависимости от значений (т.н. Partitioning). Особенности работы с БД были таковы, что раз в сутки в таблицы "вливалось" достаточно большое кол-во данных (десятки миллионов строк) и до следующего "вливания" база работала только на отдачу данных.
Проблема, а точнее даже не проблема, а пожелание заключалось в следующем: ПО, которое занималось подготовкой, фильтрацией и, собственно заливкой данных, занималось еще и тем, что вычисляло тот самый, нужный раздел (child table), в который данные нужно сложить. Это приводило к:
- невозможности менять условия разбиения данных достаточно гибко (изменения должны быть синхронизированы на стороне БД и кода);
- иногда в разделы попадали некорректные данные, так как заливка данных осуществлялась пакетно, с помощью операции COPY и нужный раздел определялся для всего пакета один;
- необходимо было заранее создавать таблицы разделов.
Решение, приведенное ниже - не панацея, но кому-то может пригодиться:
CREATE TRIGGER redirect_to_child
BEFORE INSERT ON parent
FOR EACH ROW
EXECUTE PROCEDURE redirect_to_child();
Затем, экспериментируя с процедурой redirect_to_child() выяснилось, что на стандартном PlPgsql написать достаточно гибкую функцию, которая бы перенаправляла данные в нужный раздел не получается, так как на этапе запуска функции не известно название таблицы, в которую нужно вставлять данные. Таким образом приходиться использовать EXECUTE для формирования динамического SQL, но это не решает всех проблем, так как теперь нельзя использовать NEW.*, потому что полученный SQL выполняется вне контекста триггерной функции и соответственно не видит структуры NEW.
В PostgreSQL 8.4 появилось ключевое слово USING, которое позволяет обойти проблему с использованием NEW.*, но скорость работы данного триггера оставляла желать лучшего.
В результате всех экспериментов родился небольшой велосипедик на PlPython, который сам создаёт нужные таблички и перенаправляет вставку данных. Нижеприведенный кусочек кода, решает все задачи, описанные в начале статьи, а по времени работает всего около 5-ти раз медленнее "чистой" вставки, что для моих условий было более чем приемлемо. Собственно код:
CREATE OR REPLACE FUNCTION redirect_to_child()
RETURNS trigger AS
$BODY$
import datetime
# TD['new'] -> inserted data
new_data = TD['new']
values = new_data.values()
date_occured = new_data['occured'].split()[0]
s_year, s_month = date_occured.split('-')[:2]
# TD['table_name'] -> table name, that triggered this function.
parent_table_name = TD['table_name']
# Child table name pattern is <parent_table>_<year>_<month>.
child_table_name = '_'.join([parent_table_name, s_year, s_month])
try:
insert_plan = SD[child_table_name]
except KeyError:
# Check whether child table exists.
child_table_result = plpy.execute(("SELECT * FROM information_schema.tables"
" WHERE table_catalog = CURRENT_CATALOG"
" AND table_schema = CURRENT_SCHEMA"
" AND table_name = '%s'") % (child_table_name, ))
if child_table_result.nrows() == 0 :
# Need to create child table
year = int(s_year)
month = int(s_month)
min_range_date = datetime.date(year, month, 1)
max_range_date = datetime.date(year + ((month + 1) / 12), (month + 1) % 12, 1)
create_sql = ("CREATE TABLE %(child)s ("
" id BIGINT DEFAULT nextval('%(parent)s_id_seq'::text) PRIMARY KEY,"
" CHECK ( occured >= DATE '%(min)s' AND occured < DATE '%(max)s' )"
") INHERITS (%(parent)s);") \
% {'parent': parent_table_name,
'child':child_table_name,
'min':min_range_date.isoformat(),
'max':max_range_date.isoformat() }
plpy.execute( create_sql )
plpy.execute( "ALTER TABLE %s OWNER TO tableowner;" % child_table_name )
# Prepare insertion plan.
questions_marks = ','.join(['$%d' % x for x in xrange(1, len(new_data) + 1)])
col_types = plpy.execute( ("SELECT column_name, data_type"
" FROM information_schema.columns"
" WHERE table_catalog = CURRENT_CATALOG"
" AND table_schema = CURRENT_SCHEMA"
" AND table_name = '%s'"
" AND column_name <> 'id';")
% parent_table_name );
type_hash = dict((column["column_name"], column["data_type"])
for column in col_types)
column_names = new_data.keys();
types = [type_hash[k] for k in column_names]
insert_sql = ("INSERT INTO %s (%s) VALUES (%s);" %
(child_table_name,
', '.join(column_names),
questions_marks))
insert_plan = plpy.prepare(insert_sql, types)
# Cache insertion plan for reuse in the same transaction.
SD[child_table_name] = insert_plan
# Insert data to child table
plpy.execute( insert_plan, values )
# Skip insertion to parent table
return "SKIP";
$BODY$
LANGUAGE 'plpythonu';
ALTER FUNCTION redirect_to_child() OWNER TO tableowner;
Blogspot expandable posts
Tags:
cut,
expandable,
lj-cut,
Read more,
usability
Давно я не писал сюда. Сегодня решил исправится и первым делом настроил себе красивый скрипт для длинных статей.Встречайте:Ссылка "Read more" появляется только в тех статьях, которые действительно этого заслуживают (и где я собственноручно проставил нужный тег). Работает всё предельно просто, код взят отсюда. Правда пришлось самую малость допилить.
Tuesday, 22 June 2010
Видео прокси для вещания в локальной сети
Tags:
broadcasting,
video proxy,
vlc
В период чемпионата мира по футболу очень хотелось следить за ходом матчей в живую, да вот беда - работа. Решение казалось бы банально - on-line видео трансляции, но не я один такой заинтересованный оказался. А при 30-40 одновременных потоках входящий Интернет канал оставляет остальным сотрудникам офиса лишь маленькую надежду на закачку чего бы то ни было.
Очень быстро родилась идея организовать видео прокси, которое бы принимало on-line трансляцию и раздавало видео поток в сети. Локальный трафик не так значим, как входящий интернет трафик, потому приступил к реализации. Выбор пал на VLC media player, который сначала показался несколько монстроидальным, но в дальнейшем оправдал все надежды.
Итак, что такое VLC player? Это open-source программный комплекс, позволяющий творить с видео чудеса. В плейере уже находиться масса возможностей, фактически плейер может одновременно выступать и сервером и клиентом. В поставку входят интерфейсы для удалённого управления (telnet, http), так что можем смело ставить vlc на консольную виртуальную машину (здесь и далее все команды приводятся для Ubuntu):
sudo aptitude install vlc vlc-plugin-*
Далее запускаем VLC с активным http интерфейсом удалённого управления:
vlc -vvv -I http --http-host 10.1.6.3:8181
, здесь
В принципе данного интерфейса хватает для экспериментов. Для лучшей наглядности лучше сразу же нажать кнопочку "Help".
Первым делом, я нажал кнопку "Open", ввёл адрес сервера (для экспериментов было выбрано футбольное on-line вещание ICTV) и... И насладился цветной картинкой ASCII видео в консоли удалённого сервера. Поборов восхищение и отключив видео - нашел в http интерфейсе кнопку "Stream output", которая и привела меня к победе. Догадался одновременно заполнить обе секции перед нажатием кнопки "Play":
И на последок консольный вариант запуска:
vlc -vvv -I http --http-host 10.1.6.3:8181 http://<internet.on-line.video.url> -sout "#transcode{vcodec=mp2v,vb=1024,scale=1}:std{access=http,mux=ts,dst=10.1.6.3:8080}"
index
Очень быстро родилась идея организовать видео прокси, которое бы принимало on-line трансляцию и раздавало видео поток в сети. Локальный трафик не так значим, как входящий интернет трафик, потому приступил к реализации. Выбор пал на VLC media player, который сначала показался несколько монстроидальным, но в дальнейшем оправдал все надежды.
Итак, что такое VLC player? Это open-source программный комплекс, позволяющий творить с видео чудеса. В плейере уже находиться масса возможностей, фактически плейер может одновременно выступать и сервером и клиентом. В поставку входят интерфейсы для удалённого управления (telnet, http), так что можем смело ставить vlc на консольную виртуальную машину (здесь и далее все команды приводятся для Ubuntu):
sudo aptitude install vlc vlc-plugin-*
Далее запускаем VLC с активным http интерфейсом удалённого управления:
vlc -vvv -I http --http-host 10.1.6.3:8181
, здесь
- -vvv - verbose опция (количество букв v отображает уровень логов)
- -I - включает один из интерфейсов удалённого управления (здесь http)
- --http-host - задаёт имя (ip) которое пользователь должен ввести, чтобы попасть в админ часть и порт, который будет слушать встроенный сервер
В принципе данного интерфейса хватает для экспериментов. Для лучшей наглядности лучше сразу же нажать кнопочку "Help".
Первым делом, я нажал кнопку "Open", ввёл адрес сервера (для экспериментов было выбрано футбольное on-line вещание ICTV) и... И насладился цветной картинкой ASCII видео в консоли удалённого сервера. Поборов восхищение и отключив видео - нашел в http интерфейсе кнопку "Stream output", которая и привела меня к победе. Догадался одновременно заполнить обе секции перед нажатием кнопки "Play":
- в Input (Open кнопка) адрес вещания в интернете.
- в Stream output выбрал http, ввёл адрес (всё тот же 10.1.6.3), указал порт (на этот раз 8080, чтобы не пересекаться с админкой) и отметил тип кодирования "MPEG TS"
И на последок консольный вариант запуска:
vlc -vvv -I http --http-host 10.1.6.3:8181 http://<internet.on-line.video.url> -sout "#transcode{vcodec=mp2v,vb=1024,scale=1}:std{access=http,mux=ts,dst=10.1.6.3:8080}"
Subscribe to:
Posts (Atom)