Нотатки про програмування, музику, подорожі та плівку
Про мене  •  Список нотаток  •  Плівка

Пізніше Ctrl + ↑

Изучение SQL: рекурсивные запросы

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

Общий вид рекурсивного запроса

WITH <имя> (<список столбцов>)
AS (
	SELECT    -- анкорная часть
	UNION ALL -- рекурсивная часть
        SELECT FROM <имя>
        WHERE <условие продолжения интерации>
)

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

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

Наполнение таблицы.

Код запроса:

;WITH OrgStructure AS 
(
	SELECT Id, ParentId, EmployeeType, EmployeeName
	FROM Employees
	WHERE EmployeeName = 'Jim' -- отправная точка, нам надо найти менеджера сотрудника Jim

	UNION ALL

	SELECT e.Id, e.ParentId, e.EmployeeType, e.EmployeeName
	FROM Employees as e
	JOIN OrgStructure as os
	ON e.Id = os.ParentId
)

SELECT * FROM OrgStructure
WHERE EmployeeType = 'manager' -- указываем что мы ищем менеджера.

Пример 2
Найдем первые 10 чисел Фибоначчи:

;WITH FIBONACHI AS 
(
	SELECT
		1 Iteration,
		1 SecondValue,
		2 CurrentValue
	UNION ALL

	SELECT
		Iteration + 1,
		SecondValue = CurrentValue,
		CurrentValue = SecondValue + CurrentValue
	FROM FIBONACHI
	WHERE Iteration < 10
)
SELECT CurrentValue FROM FIBONACHI

Kodak Pro Foto 100 (просрочка 2009)

Наверное самая приятная особенность данной пленки это очень широкий динамический диапазон. Также видел в интернете много мнений, что эта пленка очень хорошо подходит что Ч/Б фото. Отсняли → отсканировали → обесцветили. Снимал на Nikon N65.

GIN индекс

GIN (Generalized Inverted Index) — инвертированный индекс, который позволяет реализовать что-то на подобии полнотекстового поиска. Активно используется в PostgreSQL.

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

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

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

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

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

Ниже небольшая реализация самого простого индекса на C#:

Алгоритм поиска Ли

Алгоритм поиска пути в планарном графе. Зачастую используется в схемотехнике и в играх (стратегиях) для поиска кратчайшего пути.

Алгоритм состоит из 3 шагов:

  1. Инициализация
  2. Распространение волны
  3. Восстановление пути

Также есть 2 способа поиска пути: ортогональный и ортогонально-диагональный. Ниже на скриншотах можно увидеть работу этих двух способов.

Ортогональный поиск.
Ортогонально-диагональный поиск.

Псевдокод

Взято из Википедии.

Инициализация

Пометить стартовую ячейку 
d := 0

Распространение волны

ЦИКЛ
  ДЛЯ каждой ячейки loc, помеченной числом d
    пометить все соседние свободные непомеченные ячейки числом d + 1
  КЦ
  d := d + 1
ПОКА (финишная ячейка не помечена) И (есть возможность распространения волны)

Восстановление пути

ЕСЛИ финишная ячейка помечена
ТО
  перейти в финишную ячейку
  ЦИКЛ
    выбрать среди соседних ячейку, помеченную числом на 1 меньше числа в текущей ячейке
    перейти в выбранную ячейку и добавить её к пути
  ПОКА текущая ячейка — не стартовая
  ВОЗВРАТ путь найден
ИНАЧЕ
  ВОЗВРАТ путь не найден

Пример кода, который реализует алгоритм и выводит на экран путь (C#).

Polaroid High Definition 200 (просрочка 2002)

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

Краткие характеристики

  • ISO 200
  • Кол-во кадров 24
  • Снимал на Konica Autoreflex T3

Фото

Первое что бросается в глаза так это сдвиг цветов в зеленую сторону. Скорее всего проблема в том что давал мало света на пленку.

Попробовал отредактировать одну фотографию с помощью стандартной программы «Фото» на маке. Хотел убрать этот зеленоватый оттенок и шум. Как по мне, получилось неплохо.

Хеш-таблица

У хеш таблицы есть две особенности, которые делают ее особенной структурой данных: возможность хранить данные в формате ключ-значение и быстродействие, в среднем все операции занимают константное время O(1).

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

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

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

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

Потом когда нам нужно получить значение по ключу, то сначала мы вычисляем хеш и находим нужную ячейку в массиве. Потом мы проходимся по связанному списку и находим значение для нужного нам ключа. Но в случае коллизий скорость работы хеша может упасть до O(n). Потому что поиск элемента в массиве занимает O(1), но вот поиск по связанному списку — O(n).

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

Когда использовать?

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

Простая реализация: What is an example of a Hashtable implementation in C#?

Fujifilm Superia 100 (просрочена 2012 год.)

Нашел в закромах катушку Fujifilm Superia 100. Отснял на Konica Autoreflex T3. Из минусов могу отметить только низкое ISO, мне было достаточно тяжело фотографировать в сложных условиях освещения.

Результат

Logitech M590 или лучшая мышка для mac

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

  • Возможность работы с macOS через bluetooth без вспомогательных донглов.
  • Полноценная поддержка macOS так много мышек вели себя неадекватно.

Остановился я на Logitech M590.

Из особенностей что мне понравились

  1. Работа с 2 компьютерами. MacBook по Bluetooth, а с фрабочим компом на винде через донгл.
  2. Настройка дополнительных кнопок. И тут есть один очень крутой момент. ПО от logitech позволяет очень гибко настроить под себя мышку. В том числе на ней можно воспроизводить всем знакомые жесты macOS.

Для себя я настроил 2 режима

  • Нажатие на колесико вправо или влево — переключает рабочий стол в соответствующую сторону.
  • Передняя кнопка на левой стороне имитирует касание тачпада трема пальцами. Так зажав эту кнопку и проведя мышку вверх можно открыть Missing Control.

Минус один, если взять такую же расцветку как на картинке — то мышь очень быстро пачкается.

Раніше Ctrl + ↓