Pull to refresh
0
@vania_freemanread⁠-⁠only

User

Send message

learnopengl. Урок 1.4 — Hello Triangle

Reading time20 min
Views166K
В прошлом уроке мы таки осилили открытие окна и примитивный пользовательский ввод. В этом уроке мы разберем все азы вывода вершин на экран и воспользуемся всеми возможностями OpenGL, вроде VAO, VBO, EBO для того, чтобы вывести пару треугольников.
Заинтересовавшихся прошу под кат.
Читать дальше →
Total votes 24: ↑23 and ↓1+22
Comments8

Разделение отсканированных вместе фотографий (Python 3 + OpenCV3)

Reading time7 min
Views12K
По ящикам шкафов да пыльным полкам уже десятилетиями складируются дюжины семейных фотоальбомов. Состояние некоторых из них давно заставляет задумываться об «оцифровке» накопившегося материала. И чтобы хоть чуточку ускорить предстоящий процесс, было принято решение сканировать по несколько фотографий за раз. Однако перспектива разгребать получаемый в результате этого контент и руками дробить его на отдельные кадры мне не улыбалась. В итоге родилось решение…
Читать дальше →
Total votes 13: ↑12 and ↓1+11
Comments5

Знай сложности алгоритмов

Reading time2 min
Views990K
Эта статья рассказывает о времени выполнения и о расходе памяти большинства алгоритмов используемых в информатике. В прошлом, когда я готовился к прохождению собеседования я потратил много времени исследуя интернет для поиска информации о лучшем, среднем и худшем случае работы алгоритмов поиска и сортировки, чтобы заданный вопрос на собеседовании не поставил меня в тупик. За последние несколько лет я проходил интервью в нескольких стартапах из Силиконовой долины, а также в некоторых крупных компаниях таких как Yahoo, eBay, LinkedIn и Google и каждый раз, когда я готовился к интервью, я подумал: «Почему никто не создал хорошую шпаргалку по асимптотической сложности алгоритмов? ». Чтобы сохранить ваше время я создал такую шпаргалку. Наслаждайтесь!
Читать дальше →
Total votes 312: ↑296 and ↓16+280
Comments99

Django на production. uWSGI + nginx. Подробное руководство

Reading time7 min
Views218K
Перед вами руководство по настройке production окружения для Django. Здесь будут описаны необходимые шаги по настройке Django, uWSGI и nginx. Руководство охватывает все три компонента — полный стек серверного ПО для веб-приложений.

Подразумевается, что вы используете Unix-подобную операционную систему и менеджер пакетов, эквивалентный aptitude. Найти эквивалент aptitude почти для любой операционной системы, в том числе и для Mac OS X, для вас не составит никакого труда.

Руководство написно для версий Django 1.4 или выше. Если вы используете более раннюю версию, то вам придется самостоятельно найти wsgi модуль для нее. Также вы заметите, что файловая структура проекта будет немного отличаться от представленной здесь.

Общая идея


Веб-сервер может по запросу отдавать пользователям файлы из своей файловой системы, однако он не может напрямую работать с Djangо приложениями. Веб-серверу нужен интерфейс, который будет запускать Django приложение, передавать ему запрос от пользователя и возвращать ответ.

Для выполнения этих задач был разработан Web Server Gateway Interface — WSGI — стандарт взаимодействия Python программ и веб-сервра.

uWSGI — одна из реализаций WSGI. В этом руководстве мы установим и настроим uWSGI для создания Unix сокета и взаимодействия с веб-сервером по протоколу WSGI.
Читать дальше →
Total votes 46: ↑37 and ↓9+28
Comments54

Криптография на Python: шифрование информации и создание электронных цифровых подписей с помощью пакета PyCrypto

Reading time6 min
Views85K


Долго мучился с PyCrypto, в итоге получилась эта статья и полная реализация следующего протокола:

Этап отправки:

1. Алиса подписывает сообщение своей цифровой подписью и шифрует ее открытым ключом Боба (асимметричным алгоритмом).
2. Алиса генерирует случайный сеансовый ключ и шифрует этим ключом сообщение (с помощью симметричного алгоритма).
3. Сеансовый ключ шифруется открытым ключом Боба (асимметричным алгоритмом).
Алиса посылает Бобу зашифрованное сообщение, подпись и зашифрованный сеансовый ключ.

Этап приёма:

Боб получает зашифрованное сообщение Алисы, подпись и зашифрованный сеансовый ключ.
4. Боб расшифровывает сеансовый ключ своим закрытым ключом.
5. При помощи полученного, таким образом, сеансового ключа Боб расшифровывает зашифрованное сообщение Алисы.
6. Боб расшифровывает и проверяет подпись Алисы.
Читать дальше →
Total votes 14: ↑13 and ↓1+12
Comments6

Мониторинг выполнения задач в IPython Notebook

Reading time2 min
Views36K
Хотел бы поделиться простым, но полезным инструментом. Когда много работаешь с данными, часто возникают примитивные, но долгие операции, например: «скачать 10 000 урлов», «прочитать файл на 2Гб, и что-то сделать с каждой строчкой», «распарсить 10 000 html-файлов и достать заголовки». Долго смотреть в зависший терминал тревожно, поэтому долгое время я использовал следующий гениальный код:
def log_progress(sequence, every=10):
    for index, item in enumerate(sequence):
        if index % every == 0:
            print >>sys.stderr, index,
        yield item


Эта функция прекрасна, больше года она кочевала у меня из задачи в задачу. Но недавно я заметил в стандартной поставке Jupyter виджет IntProgress и понял, что пора что-то менять:

Читать дальше →
Total votes 42: ↑39 and ↓3+36
Comments11

Проектирование простых приложений в Flask

Reading time11 min
Views52K
Данная статья, размещенная в репозитории Flask на GitHub, является плодом коллективного творчества небезразличных программистов, а изначальный её автор — Brice Leroy. Она представляет собой достаточно полезный для начинающих материал по Flask. Лично для меня он стал ответом на многие простые вопросы, основным из которых был «как структурировать проект».

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

Описанный пример протестирован на Python 3.5, Flask 0.10, Flask-SQLAlchemy 2.1, Flask-WTF 0.9.

Читать дальше →
Total votes 11: ↑7 and ↓4+3
Comments11

Стандарты симметричного шифрования стран СНГ на Python

Reading time4 min
Views22K
image
Первые недели нового года самое подходящее время для того, чтобы уютно устроившись у окошка, вспомнить что же нам принес год ушедший.
А принес он нам два новых стандарта шифрования. Российский стандарт ГОСТ Р 34.12-2015 (блочный шифр Кузнечик). И украинский ДСТУ 7624:2014 (блочный шифр Калина). Холодными, зимними вечерами нельзя упускать такой удачный повод покодить. Под катом краткое описание алгоритмов и их реализация на Python. А чтобы новым шифрам было веселее, разбавим их общество белорусским СТБ 34.101.31-2007.
Читать дальше →
Total votes 13: ↑13 and ↓0+13
Comments3

Импорт словаря в Lingualeo.com

Reading time3 min
Views23K


Предыстория


Для импорта слов в Lingualeo.com есть несколько решений:

  • Приложения для браузера или телефонов:
  • Добавление слов на сайте.

Минусы этих способов в том, что вносить слова можно только по одному. Нам необходима реализация, которая позволит добавлять несколько слов за раз.
Читать дальше →
Total votes 12: ↑11 and ↓1+10
Comments16

О бедной рекурсии замолвите слово, или всё, что вы не знали и не хотите о ней знать

Reading time8 min
Views77K
Рекурсия: см. рекурсия.

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

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

— Как она сложена?
— Превосходно! Только рука немного торчит из чемодана.

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

  def fib(n):
    if n<0: raise Exception("fib(n) defined for n>=0")
    if n>1: return fib(n-1) + fib(n-2)
    return n

приходится городить всевозможные грязные хаки, начиная от:

  @memoized
  def fib(n):
    if n<0: raise Exception("fib(n) defined for n>=0")
    if n>1: return fib(n-1) + fib(n-2)
    return n

И заканчивая вообще:

  def fib(n):
    if n<0: raise Exception("fib(n) defined for n>=0")
    n0 = 0
    n1 = 1
    for k in range(n):
      n0, n1 = n1, n0+n1
    return n0

Читать дальше →
Total votes 55: ↑44 and ↓11+33
Comments63

The Chrome Dev Summit в прямом эфире, день второй

Reading time4 min
Views3.1K
Привет, Хабр! Второй день он-лайн трансляции главного Chrome-мероприятия этого года: Google Chrome Dev Summit 2015 начнётся совсем скоро!



За ночь с географией ничего не случилось, Пало-Альто как находилось на другой стороне глобуса, так и находится. Прямая трансляция будет проходить в не самое удобное время (начало — в 20:30 по Мск), но даже если вы не сможете посмотреть её в прямом эфире, завтра станут доступны видеозаписи.
Читать дальше →
Total votes 9: ↑8 and ↓1+7
Comments0

NoSQL базы данных: понимаем суть

Reading time9 min
Views570K
В последнее время термин “NoSQL” стал очень модным и популярным, активно развиваются и продвигаются всевозможные программные решения под этой вывеской. Синонимом NoSQL стали огромные объемы данных, линейная масштабируемость, кластеры, отказоустойчивость, нереляционность. Однако, мало у кого есть четкое понимание, что же такое NoSQL хранилища, как появился этот термин и какими общими характеристиками они обладают. Попробуем устранить этот пробел.


Читать дальше →
Total votes 137: ↑133 and ↓4+129
Comments75

АВЛ-деревья

Reading time9 min
Views403K
Если в одном из моих прошлых постов речь шла о довольно современном подходе к построению сбалансированных деревьев поиска, то этот пост посвящен реализации АВЛ-деревьев — наверное, самого первого вида сбалансированных двоичных деревьев поиска, придуманных еще в 1962 году нашими (тогда советскими) учеными Адельсон-Вельским и Ландисом. В сети можно найти много реализаций АВЛ-деревьев (например, тут), но все, что лично я видел, не внушает особенного оптимизма, особенно, если пытаешься разобраться во всем с нуля. Везде утверждается, что АВЛ-деревья проще красно-черных деревьев, но глядя на прилагаемый к этому код, начинаешь сомневаться в данном утверждении. Собственно, желание объяснить на пальцах, как устроены АВЛ-деревья, и послужило мотивацией к написанию данного поста. Изложение иллюстрируется кодом на С++.

Читать дальше →
Total votes 69: ↑62 and ↓7+55
Comments50

Бинарные деревья поиска и рекурсия – это просто

Reading time8 min
Views589K
Существует множество книг и статей по данной теме. В этой статье я попробую понятно рассказать самое основное.

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

image
Рис. 1 Бинарное дерево
Читать дальше →
Total votes 43: ↑32 and ↓11+21
Comments9

Поисковые подсказки изнутри

Reading time11 min
Views27K


Ночная зала. Тысячи таинственных ликов в темноте, подсвеченных голубоватым свечением мониторов. Оглушительный треск миллиона клавиш. Подобные выстрелам автомата удары по клавишам «Enter». Зловещее стрекотание сотен тысяч мышек… Так, наверняка, играло воображение каждого разработчика высоконагруженной системы. И если его вовремя не остановить, то может выйти целый триллер или фильм ужасов. Но в данной статье мы будем гораздо ближе к земле. Мы кратко рассмотрим известные подходы к решению задачи поисковых подсказок, как мы научились делать их полнотекстовыми, а также расскажем о парочке уловок, на которые мы пошли, чтобы придать им скорости, но при этом не научить жадности к ресурсам. В конце статьи вас ждёт бонус — небольшой рабочий пример.
Читать дальше →
Total votes 64: ↑60 and ↓4+56
Comments14

Внешняя сортировка с O(1) дополнительной памяти

Reading time9 min
Views36K
Прочитав эту статью, я вспомнил, как писал внешнюю сортировку, которая использовала O(1) внешней памяти. Функция получала бинарый файл и максимальный размер памяти, которую она могла выделить под массив:

void ext_sort(const std::string filename, const size_t memory)

Я использовал алгоритм из Effective Performance of External Sorting with No Additional Disk Space:

  1. Разделим файл на блоки, которые помещаются в доступную память. Обозначим эти блоки Block_1, Block_2, …, Block_(S-1), Block_S. Установим P = 1.
  2. Читаем Block_P в память.
  3. Отсортируем данные в памяти и запишем назад в Block_P. Установим P = P + 1, и если P ≤ S, то читаем Block_P в память и повторяем этот шаг. Другими словами, отсортируем каждый блок файла.
  4. Разделим каждый блок на меньшие блоки B_1 и B_2. Каждый из таких блоков занимает половину доступной памяти.
  5. Читаем блок B_1 блока Block_1 в первую половину доступной памяти. Установим Q = 2.
  6. Читаем блок B_1 блока Block_Q во вторую половину доступной памяти.
  7. Объеденим массивы в памяти с помощью in-place слияния, запишем вторую половину памяти в блок B_1 блока Block_Q и установим Q = Q + 1, если Q ≤ S, читаем блок B_1 блока Block_Q во вторую половину доступной памяти и повторяем этот шаг.
  8. Записываем первую половину доступной памяти в блок B_1 блока Block_1. Так как мы всегда оставляли в памяти меньшую половину элементов и провели слияние со всеми блоками, то в этой части памяти хранятся M минимальных элементы всего файла.
  9. Читаем блок B_2 блока Block_S во вторую половину доступной памяти. Установим Q = S −1.
  10. Читаем блок B_2 блока Block_Q в первую половину доступной памяти.
  11. Объеденим массивы в памяти с помощью in-place слияния, запишем первую половину доступной памяти в блок B_2 блока Block_Q и установим Q = Q −1. Если Q ≥ 1 читаем блок B_2 блока Block_Q в первую половину доступной памяти и повторяем этот шаг.
  12. Записываем вторую половину доступной памяти в блок B_2 блока Block_S. Аналогично шагу 8, тут хранятся максимальные элементы всего файла.
  13. Начиная от блока B_2 блока Block_1 и до блока B_1 блока Block_S, определим новые блоки в файле и снова пронумеруем их Block_1 to Block_S. Разделим каждый блок на блоки B_1 и B_2. Установим P = 1.
  14. Читаем B_1 и B_2 блока Block_P в память. Объеденим массивы в памяти. запишем отсортированный массив назад в Block_P и установим P = P +1. Если P ≤ S, повторяем этот шаг.
  15. Если S > 1, возвращаемся к шагу 5. Каждый раз мы выделяем M минимальных и максимальных элементов, записываем их в начало и конец файла соответственно, а потом делаем то же самое с оставшимися элементами, пока не дойдем до середины файла.

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

Реализуем алгоритм на C++.
Читать дальше →
Total votes 28: ↑23 and ↓5+18
Comments9

Шокирующий Objective-C для Java программистов

Reading time4 min
Views26K

О чем эта статья?


Два факта. В мире много Java программистов. Популярность Objective-C растет. Вывод: Java программист, изучающий Objective-C не такая уж редкость. Если знать ключевые различия между языками, то можно эффективно использовать существующие знания Java и быстрее начать писать на Objective-C.
Читать дальше →
Total votes 78: ↑65 and ↓13+52
Comments161

Тестирование в Яндексе. Как сделать отказоустойчивый грид из тысячи браузеров

Reading time7 min
Views41K
Любой специалист, причастный к тестированию веб-приложений, знает, что большинство рутинных действий на сервисах умеет делать фреймворк Selenium. В Яндексе в день выполняются миллионы автотестов, использующих Selenium для работы с браузерами, поэтому нам нужны тысячи различных браузеров, доступных одновременно и 24/7. И вот тут начинается самое интересное.



Selenium с большим количеством браузеров имеет много проблем с масштабированием и отказоустойчивостью. После нескольких попыток у нас получилось элегантное и простое в обслуживании решение, и мы хотим поделиться им с вами. Наш проект gridrouter позволяет организовать отказоустойчивый Selenium-грид из любого количества браузеров. Код выложен в open-source и доступен на Github. Под катом я расскажу, на какие недостатки Selenium мы обращали внимание, как пришли к нашему решению, и объясню, как его настроить.
Читать дальше →
Total votes 63: ↑57 and ↓6+51
Comments31

Функциональные тесты: Django + Selenium WebDriver и 3 варианта на Ваш выбор

Reading time8 min
Views19K
image

«В жизни каждого Django-разработчика наступает момент, когда он решительно рвет со своим прошлым, лишенным функционального тестирования!»

Об этом и поговорим.
Читать дальше →
Total votes 12: ↑10 and ↓2+8
Comments0

WebSocket-чат на Tornado для вашего Django-проекта

Reading time28 min
Views68K
TornadoНедавно я запустил сайт backgrounddating.com и написал об этом здесь, на Хабрахабре. Разумеется, я уже тогда рассказал о некоторых технических деталях реализации этого проекта, но об одной из возможностей сайта я бы хотел написать отдельно, тем более, что документации (как на русском, так и на английском) на эту тему в Интернете пока что довольно мало. Итак, речь пойдёт о чате в реальном времени между двумя пользователями. Задача состоит в том, чтобы любой пользователь мог отправлять другим пользователям сообщения, и, если у получателя сообщения открыт чат с этим пользователям, то он сразу же видел входящие сообщения (а в ином случае он мог прочитать сообщения позже: то есть при открытии чата загружается история последних сообщений).

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

Сразу уточню, что это не единственный способ реализовать подобное. Вы можете использовать другой асинхронный веб-сервер (например node.js), можете использовать другую очередь сообщений (или вообще её не использовать, если вам подходят особенности такого варианта: с пользователями одного канала обязательно общается один и тот же worker веб-сервера). Я даже не утверждаю, что этот вариант самый лучший (но в данном случае он подошёл лучше всех). В конце концов, мы здесь вообще не будем рассматривать костыли (long polling, Flash) для старых браузеров (а это почти все версии IE, например), не поддерживающих веб-сокеты, и даже не будем рассматривать возможность подключаться из тех браузеров, которые уже поддерживают протокол WebSocket, но не стандартизированную версию (RFC 6455), а одну из устаревших. О том, как можно включить поддержку устаревшей версии «draft 76» (она же «hixie-76»), смотрите в документации Tornado.
Читать дальше →
Total votes 56: ↑43 and ↓13+30
Comments17
1

Information

Rating
Does not participate
Location
Canberra, Australian Capital Territory, Австралия
Date of birth
Registered
Activity