Булева логика и фильтры: вопросы для собеседования (часть 3)

AND, OR, NOT, законы де Моргана, приоритет операторов — булева логика лежит в основе фильтрации данных в SQL и Python. На собеседовании дают сложное условие с вложенными AND/OR и просят определить, какие строки пройдут фильтр. Ошибки в логических выражениях — одна из самых частых причин неправильных результатов.

Качество данных и инвариантыВоронки и когортные рассужденияJOIN и кардинальностьПостановка задачиДоли и процентыSanity-check и оценкаСегментация и конфаундингТеория множеств и дедупликацияВзвешенные средние и смешение

Вопросы 1115 из 20

11Какое условие эквивалентно `NOT (is_paying = 1 AND has_subscription = 1)` по правилу `De Morgan`?
A`NOT (is_paying = 1) AND NOT (has_subscription = 1)`
B`is_paying = 0 AND has_subscription = 0`
C`NOT (is_paying = 1) OR NOT (has_subscription = 1)`
D`is_paying = 1 OR has_subscription = 1`
Ответ: По `De Morgan` `NOT (is_paying = 1 AND has_subscription = 1)` равносильно `NOT (is_paying = 1) OR NOT (has_subscription = 1)`.

Чтобы выражение `A AND B` стало ложным, достаточно, чтобы ложным оказалось хотя бы одно из условий. Поэтому отрицание всей скобки превращается в `OR` между отрицаниями частей. Ошибка — заменить на `NOT A AND NOT B`, потому что это уже «`ни один` из двух», а не «не одновременно `оба`».

12Сегмент определён как `is_paying = 1 OR has_trial = 1`. Нужно выбрать пользователей, которые не входят в этот сегмент. Какое условие корректно?
A`NOT (is_paying = 1 OR has_trial = 1)`
B`NOT (is_paying = 1) OR NOT (has_trial = 1)`
C`is_paying = 0 OR has_trial = 0`
D`NOT (is_paying = 1 AND has_trial = 1)`
Ответ: Для отрицания `A OR B` по `De Morgan` используется `NOT A AND NOT B`, что эквивалентно `NOT (A OR B)`.

Если сегмент задан как `is_paying = 1 OR has_trial = 1`, то «не в сегменте» значит, что не выполняется `ни один` из двух признаков. Это записывается как `NOT (is_paying = 1 OR has_trial = 1)` или эквивалентно `NOT (is_paying = 1) AND NOT (has_trial = 1)`. Вариант с `OR` между отрицаниями слишком мягкий и пропускает пользователей, у которых один из признаков всё ещё истинный.

13Для двух флагов `used_card = 1` и `used_paypal = 1` нужно выбрать пользователей, которые использовали `exactly one` способ оплаты. Какое условие соответствует этому, используя комбинацию `OR`, `AND` и `NOT` без перечисления двух кейсов?
A`used_card = 1 OR used_paypal = 1`
B`NOT (used_card = 1 OR used_paypal = 1)`
C`(used_card = 1 OR used_paypal = 1) AND NOT (used_card = 1 AND used_paypal = 1)`
D`used_card = 1 AND used_paypal = 1`
Ответ: `exactly one` можно записать как `at least one` `AND` `NOT` `оба` одновременно.

Первая часть `(A OR B)` гарантирует, что выполнено хотя бы одно условие. Вторая часть `NOT (A AND B)` запрещает ситуацию, когда истинны `оба` условия одновременно. В сочетании это даёт `ровно один` истинный флаг. Такая форма удобна, когда сами условия длинные и их не хочется дублировать в двух ветках.

14Есть условия `is_paying = 1` и `is_active = 1`. Как правильно интерпретировать фильтр `NOT (is_paying = 1 AND is_active = 1)`?
AОставляет только строки, где `is_paying = 1 AND is_active = 1`.
BОставляет только строки, где `NOT (is_paying = 1) AND NOT (is_active = 1)`.
CОставляет строки, где `is_paying = 1 OR is_active = 1`.
DИсключает только строки, где выполнены `оба` условия одновременно; все остальные проходят.
Ответ: Отрицание `AND` исключает совместное выполнение, но не требует, чтобы оба условия были ложными.

Условие `NOT (A AND B)` означает «не верно, что одновременно A и B». Это включает три случая: A ложь и B истина, A истина и B ложь, A ложь и B ложь. Ошибка — заменить это на `NOT A AND NOT B`, что соответствует более строгому «`ни один` из двух».

15Вы хотите выбрать платящих пользователей из RU или KZ: `is_paying = 1` и страна одна из двух. Какой вариант корректно выражает это без ошибки приоритета `AND`/`OR`?
A`country = 'RU' OR country = 'KZ' AND is_paying = 1`
B`(country = 'RU' OR country = 'KZ') AND is_paying = 1`
C`country = 'RU' AND country = 'KZ' AND is_paying = 1`
D`country = 'RU' OR (country = 'KZ' OR is_paying = 1)`
Ответ: Чтобы блок `country = 'RU' OR country = 'KZ'` не распался, его нужно взять в скобки перед `AND` с `is_paying = 1`.

Без скобок `AND` выполняется раньше `OR`, поэтому `country = 'KZ' AND is_paying = 1` сгруппируется вместе, а `country = 'RU'` станет отдельной веткой `OR`. В результате в выборку попадут все RU пользователи независимо от оплаты. Скобки делают группировку явной и предотвращают типичную ошибку фильтра.

1234

Хотите тренировать интерактивно?

В приложении — таймер, прогресс, стрики и 1700+ вопросов по всем темам.

Тренировать в Telegram

Другие темы: Логика

Качество данных и инвариантыВоронки и когортные рассужденияJOIN и кардинальностьПостановка задачиДоли и процентыSanity-check и оценкаСегментация и конфаундингТеория множеств и дедупликацияВзвешенные средние и смешение