🔥Какое оно - эстетическое удовольствие аналитика?
Мы очень любим применять в своей работе фишки, конструкции, трюки, если хотите, которые не только удобные, но еще и красивые!
🔹Как часто вы оказывались в ситуации, где вы запустили цикл и ждете, и ждете, и ждете, а он все еще выполняется? Такое может быть если код не очень оптимизирован или вы просто обрабатываете много данных. Иного предсказать сколько времени займет выполнение кода - сложно. И эта неопределенность постоянно щекотит наши нервы.
🪄Что, если мы покажем вам волшебную палочку, которая спасет вас от неизвестности и ожидания! Это волшебство называется
С помощью этого модуля вы сможете отследить ход выполнения вашего цикла, да еще и сделать это красиво. Все, что вам понадобится сделать, это импортировать
🤩 Очень советуем опробовать этот модуль, потому что это - настоящее эстетическое удовольствие аналитика!
#python
Мы очень любим применять в своей работе фишки, конструкции, трюки, если хотите, которые не только удобные, но еще и красивые!
🔹Как часто вы оказывались в ситуации, где вы запустили цикл и ждете, и ждете, и ждете, а он все еще выполняется? Такое может быть если код не очень оптимизирован или вы просто обрабатываете много данных. Иного предсказать сколько времени займет выполнение кода - сложно. И эта неопределенность постоянно щекотит наши нервы.
🪄Что, если мы покажем вам волшебную палочку, которая спасет вас от неизвестности и ожидания! Это волшебство называется
TQDM!С помощью этого модуля вы сможете отследить ход выполнения вашего цикла, да еще и сделать это красиво. Все, что вам понадобится сделать, это импортировать
TQDM, и обернуть в него итерируемый объект. Вуаля!from tqdm import tqdmУ вас появится автоматически обновляемая строка прогресса:
from time import sleep
# оборачиваем итератор range(100) классом tqdm()
for i in tqdm(range(100)):
sleep(0.1)
>> 13%|█▎ | 13/100 [00:01<00:08, 9.82it/s]А если вы работаете в ноутбуке, можете импортировать
tqdm.notebook и тогда эта строка прогресса будет отображаться в html, что делает её еще более интересной (см. гифку под постом).from tqdm.notebook import tqdmТеперь, вам не придется, например, добавлять
from time import sleep
for i in tqdm(range(100)):
sleep(0.1)
print в цикл, чтобы понимать на какой стадии вы находитесь. С TQDM вы можете расслабиться и просто наблюдать!🤩 Очень советуем опробовать этот модуль, потому что это - настоящее эстетическое удовольствие аналитика!
#python
👍12🔥4
🔥 Бесплатный мастер-класс по SQL
Приветствую!
На связи Андрон, основатель IT Resume & Simulative. Хочу пригласить вас на свой мастер-класс по SQL: «Расчет продуктовых метрик и активности пользователей» 🔥
Мастер-класс пройдет 22 февраля, в 20:10 по Мск. Нам предстоит проанализировать активность пользователей платформы IT Resume на основании посещений платформы и решения задач юзерами.
С помощью SQL-запросов мы посчитаем:
- MAU/WAU/DAU
- sticky factor
- когортный анализ lifetime методом нахождения интеграла от n-day retention
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉🏻 https://t.iss.one/simulative_master_class_bot?start=c1669653664751-ds
Кстати, все участники мастер-класса получат в подарок конспект с разбором метрик, шаблонами SQL-запросов и полезными советами 🎁
До встречи на мастер-классе! 🙂
Приветствую!
На связи Андрон, основатель IT Resume & Simulative. Хочу пригласить вас на свой мастер-класс по SQL: «Расчет продуктовых метрик и активности пользователей» 🔥
Мастер-класс пройдет 22 февраля, в 20:10 по Мск. Нам предстоит проанализировать активность пользователей платформы IT Resume на основании посещений платформы и решения задач юзерами.
С помощью SQL-запросов мы посчитаем:
- MAU/WAU/DAU
- sticky factor
- когортный анализ lifetime методом нахождения интеграла от n-day retention
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉🏻 https://t.iss.one/simulative_master_class_bot?start=c1669653664751-ds
Кстати, все участники мастер-класса получат в подарок конспект с разбором метрик, шаблонами SQL-запросов и полезными советами 🎁
До встречи на мастер-классе! 🙂
👍18🔥8
🔥 Задача с собеседования по SQL
Сегодня любимая рубрика - разбор задачи с собеседования!
Есть две таблицы: items_available и colors. Наша задача - извлечь доступные цвета в текстовом формате.
Звучит просто, не так ли? Но как всегда, дьявол кроется в деталях.
items_available
В этом решении столбец colors_available делят на два разных столбца. Это достигается с помощью функций
🛑 Этот запрос решает задачу, но не кажется ли вам, что можно сделать запрос короче? Да и в целом, получается какое-то нагромождение.
2️⃣ Итак, версия второго кандидата (карточка 2).
Здесь, мы не используем ни POSITION, ни LEFT, ни SUBSTRING, их всех заменяет
Существенно короче и приятнее стал выглядеть запрос, согласитесь?
3️⃣ Но подождите, это еще не все! Третье решение - самое элегантное из всех. Есть только одно НО. Этот запрос сработает, только при условии, что столбец colors_available - не текстовый, а является массивом чисел. (карточка 3)
🟢 В этом случае, нам даже не пришлось придумывать какими пользоваться функциями, нас спас простой
У вас есть идеи как еще решить эту задачу? 😏
#sql #interview_problems
Сегодня любимая рубрика - разбор задачи с собеседования!
Есть две таблицы: items_available и colors. Наша задача - извлечь доступные цвета в текстовом формате.
Звучит просто, не так ли? Но как всегда, дьявол кроется в деталях.
items_available
| item_id | colors_available |colors
|---------|------------------|
| 1 | 1, 2 |
| 2 | 3, 4 |
| 3 | 5, 4 |
| 4 | 3, 4 |
| 5 | 6, 2 |
| color_id | color_name |Результат
|----------|------------|
| 1 | Black |
| 2 | White |
| 3 | Silver |
| 4 | Gold |
| 5 | Pink |
| 6 | Green |
| item_id | colors |1️⃣ Начнем с первого предложенного варианта решения (карточка 1).
|---------|--------------|
| 1 | Black, White |
| 2 | Silver, Gold |
| 3 | Pink, Gold |
| 4 | Silver, Gold |
| 5 | Green, White |
В этом решении столбец colors_available делят на два разных столбца. Это достигается с помощью функций
LEFT и POSITION. В POSITION передается запятая и она возвращает нам индекс вхождения этой запятой в строку, а при помощи LEFT мы обрезаем строку до позиции запятой минус единица. Примерно все то же самое происходит для второго числа, только теперь используется SUBSTRING. Дальше все это объединяется c табличкой colors, и с помощью CONCAT - выводят цвета через запятую. 🛑 Этот запрос решает задачу, но не кажется ли вам, что можно сделать запрос короче? Да и в целом, получается какое-то нагромождение.
2️⃣ Итак, версия второго кандидата (карточка 2).
Здесь, мы не используем ни POSITION, ни LEFT, ни SUBSTRING, их всех заменяет
SPLIT_PART. В SPLIT_PART можно передать строку, которую мы хотим разделить, потом разделитель (в нашем случае запятая), а затем указать какую часть из получившихся сплитов взять. И мы сразу джойним таблички по этому условию. Существенно короче и приятнее стал выглядеть запрос, согласитесь?
3️⃣ Но подождите, это еще не все! Третье решение - самое элегантное из всех. Есть только одно НО. Этот запрос сработает, только при условии, что столбец colors_available - не текстовый, а является массивом чисел. (карточка 3)
🟢 В этом случае, нам даже не пришлось придумывать какими пользоваться функциями, нас спас простой
ANY. С его помощью мы сопоставляем любой элемент в массиве colors_available с соответствующим id цвета в таблице colors.У вас есть идеи как еще решить эту задачу? 😏
#sql #interview_problems
🔥13👍6
🔥 [Ласт-колл] На бесплатный мастер-класс по SQL
Это Андрон, основатель IT Resume & Simulative. Просто хочу напомнить, что сегодня в 20:10 по Мск я провожу мастер-класс по SQL: «Расчет продуктовых метрик и активности пользователей» 🔥
Будем считать MAU/WAU/DAU, sticky factor и делать когортный анализ lifetime. В конце всех ждут подробные конспекты с шаблонами кода и полезными советами 🎁
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉🏻 https://t.iss.one/simulative_master_class_bot?start=c1669653664751-ds
До встречи на мастер-классе 🙂
Это Андрон, основатель IT Resume & Simulative. Просто хочу напомнить, что сегодня в 20:10 по Мск я провожу мастер-класс по SQL: «Расчет продуктовых метрик и активности пользователей» 🔥
Будем считать MAU/WAU/DAU, sticky factor и делать когортный анализ lifetime. В конце всех ждут подробные конспекты с шаблонами кода и полезными советами 🎁
🔗 Чтобы не пропустить трансляцию и получить конспект, переходите по ссылке 👉🏻 https://t.iss.one/simulative_master_class_bot?start=c1669653664751-ds
До встречи на мастер-классе 🙂
🔥10👍4👎1
🔥 Генератор yield в Python
Вашей реакции на пост о
Из примера в прошлом посте видно, что
Итак, как же он работает? 🧐
Допустим, мы хотим получить квадраты чисел от 1 до 10. Мы могли бы создать список и с помощью
Мы задали функцию-генератор
У генераторов еще есть метод
Итак, при каждой итерации, Python запускал код до тех пор, пока не сталкивался с оператором
Когда функция вызывается в следующий раз, выполнение продолжается с этого “замороженного” момента. И так продолжается до тех пор, пока генератор не будет исчерпан. Если после того, как генератор выдал все значения, вызвать его снова - получим ошибку
🔵 Где пригодится yield?
→ При генерации больших последовательностей - с помощью
→ При чтении больших файлов.
→ При создании пайплайнов обработки. Вы можете постепенно проходить все этапы для каждого элемента, а не обрабатывать все элементы сразу. Например:
#python
Вашей реакции на пост о
yield можно только позавидовать. За нами теперь должок, удовлетворить ваш интерес и рассказать об этом загадочном генераторе. Мы посмотрим как это работает и где применимо.Из примера в прошлом посте видно, что
yield можно использовать в функции вместо return. И тогда получается генератор, который вычисляет не всё сразу, а генерирует элемент на ходу.Итак, как же он работает? 🧐
Допустим, мы хотим получить квадраты чисел от 1 до 10. Мы могли бы создать список и с помощью
append добавлять в него элементы, но мы заменим эту привычную конструкцию на yield:def squares(x=0):Получим:
while x < 10:
x = x + 1
yield x*x
for i in squares():
print(i)
1🟢 Что произошло?
4
9
16
25
36
49
64
81
100
Мы задали функцию-генератор
squares(), а затем с помощью цикла for вывели элементы, вычисленные функцией. У генераторов еще есть метод
next(). Например, мы бы вызывали next(squares()), чтобы получить следующее значение. Но нам бы пришлось написать это 10 раз, так что лучше воспользуемся циклом.Итак, при каждой итерации, Python запускал код до тех пор, пока не сталкивался с оператором
yield. Затем он выдавал вычисленное значение, а функция, как бы “замораживалась” в этом состоянии, готовясь возобновить выполнение с этого же места.Когда функция вызывается в следующий раз, выполнение продолжается с этого “замороженного” момента. И так продолжается до тех пор, пока генератор не будет исчерпан. Если после того, как генератор выдал все значения, вызвать его снова - получим ошибку
StopIteration. Мы можем переопределить генератор, и тогда все начнётся заново.🔵 Где пригодится yield?
→ При генерации больших последовательностей - с помощью
yield мы сохраним внушительный объем памяти.→ При чтении больших файлов.
Yield позволит пройтись по одной строке за раз, а не считывать весь файла целиком в память.→ При создании пайплайнов обработки. Вы можете постепенно проходить все этапы для каждого элемента, а не обрабатывать все элементы сразу. Например:
def read_csv(filename):🟡 Таким образом,
# читаем строки из файла и обязательно указываем yield
yield line
def filter_columns(rows, indices):
# что-то фильтруем
yield [row[i] for i in indices]
def convert_to_float(rows):
# производим какие-то преобразования
yield [float(cell) for cell in row]
def compute_average(rows):
# производим вычисления
yield total / count
# Создаем пайплайн
pipeline = compute_average(
convert_to_float(filter_columns(
read_csv("data.csv"), [1, 2, 3])))
average = next(pipeline)
print(f"Average: {average:.2f}")
yield - мощный инструмент, который позволяет создавать генераторы, и получать значения на ходу. Порой, это делает его незаменимым при работе с объемными данными и файлами. Потренируйтесь использовать yield и убедитесь, как он может упростить ваш код и сохранить память!#python
🔥17❤4👍3
🔥 В чем разница между IN и ANY в SQL?
С завидной регулярностью наши студенты задают вопрос: в чем разница между конструкциями IN и ANY в SQL? Если вы сталкивались с ними хоть раз, то, вероятно, замечали, что делают они примерно одно и то же. Но в чем же различия?! Давайте устраним возможную путаницу и разберем пусть небольшие, но важные различия между этими конструкциями!
Мы используем
- выражение IN (подзапрос)
- выражение IN (значение [, ...])
Аналогично, два варианта использования конструкции
- выражение оператор ANY (подзапрос)
- выражение оператор ANY (массив)
🟢 IN и ANY с подзапросами
Давайте сначала посмотрим на случаи с подзапросами. Мы привыкли использовать
И если мы посмотрим на планы выполнения - увидим, что планы выглядят аналогично ( т.к.
Первый:
🔵 IN и ANY с простыми значениями
Во втором случае использования
В то время как
🟣 Таким образом, несмотря на то, что конструкции
#sql
С завидной регулярностью наши студенты задают вопрос: в чем разница между конструкциями IN и ANY в SQL? Если вы сталкивались с ними хоть раз, то, вероятно, замечали, что делают они примерно одно и то же. Но в чем же различия?! Давайте устраним возможную путаницу и разберем пусть небольшие, но важные различия между этими конструкциями!
Мы используем
IN в двух случаях:- выражение IN (подзапрос)
- выражение IN (значение [, ...])
Аналогично, два варианта использования конструкции
ANY:- выражение оператор ANY (подзапрос)
- выражение оператор ANY (массив)
🟢 IN и ANY с подзапросами
Давайте сначала посмотрим на случаи с подзапросами. Мы привыкли использовать
IN с ними, не так ли? Но написать IN это то же, что написать = ANY. Это прямо указано в документации: IN is equivalent to = ANY.И если мы посмотрим на планы выполнения - увидим, что планы выглядят аналогично ( т.к.
IN заменяется на = ANY). Убедитесь в этом, прогнав два запроса:Первый:
explain select * from foo1 where id in (select id from foo2);
Второй: explain select * from foo1 where id = any (select id from foo2);
Итак, можно ли сказать, что ANY гораздо более универсален, поскольку его можно комбинировать со многими операторами, а не только с =, как это предполагает IN? Может быть. Но давайте проверим использование не с подзапросами.🔵 IN и ANY с простыми значениями
Во втором случае использования
IN принимает список значений, разделенных запятыми. Он возвращает true, если значение совпадает с любым из значений в списке.SELECT * FROM studentsЭтот запрос вернет всех учащихся, с оценками A, B или C.
WHERE grade IN ('A', 'B', 'C');
В то время как
ANY принимает массив. Он также возвращает true, если значение совпадает с любым из значений в массиве.SELECT * FROM productsПолучим все товары, цена которых превышает 10, 20 или 30.
WHERE price > ANY (ARRAY[10, 20, 30]);
🟣 Таким образом, несмотря на то, что конструкции
IN и ANY могут показаться похожими, они остаются разными. Более того, существует мнение, что конструкция ANY покрывает большее количество запросов и оттого лучше, чем IN. Но не будем выбирать любимчика, ведь наша задача - понимать механику работы каждой конструкции и правильно их использовать!#sql
👍13🔥6
🔥Продолжаем говорить про О-нотацию
Из предыдущих постов мы уже знаем, как работает
А сегодня поговорим про логарифмическую сложность, квадратичную, экспоненциальную и другие типы.
🟢 Сложность O(n log n)
Фактически, все эффективные алгоритмы сортировки представляют собой O(n log n) сложность: сортировка слиянием (merge), пирамидальная сортировка (heap), быстрая сортировка, а еще Timsort (изобретенный Тимом Питерсом алгоритм, который используется методом
Например, отсортировать
🔵 Сложность O(n^2)
Если требуется найти повторяющиеся книги на несортированной полке, это уже квадратичная сложность. Например, на полке стоят 100 несортированных книг, мы берем одну и ищем дубли среди остальных 99, потом берём другую и снова проверяем оставшиеся. Очень затратно: проверка 100 книг займёт 100 × 100, или 10 000 шагов, причем проверка 200 займёт уже 40 000 шагов - в четыре раза больше.
В реальном мире, именно для этого нам необходимо знание
Итак, остались те, чьи имена нельзя произносить: экспоненциальная
🟣 Сложность O(2^n)
Допустим, на полке 2 книги, и мы будем собирать все возможные комбинации книг: первая комбинация - пустая полка, вторая - книга A, третья - книга B и последняя - обе книги на полке. Для 3 книг получим уже 8 комбинаций. Так вот, это - экспоненциальный алгоритм. Причем, обратите внимание, нас интересуют не перестановки, а только комбинации.
🔴 Сложность O(n!)
Перестановки, как раз, будут отвечать за факториальную сложность: если у нас на полке
И оба этих алгоритма крайне плохо масштабируются: даже для малых
💡 Наконец переходим от теории к практике!
Что из себя представляет каждый из алгоритмов мы рассмотрели, практически, под лупой. Мы также понимаем, как увеличение входных данных (количества книг) повлияет на каждый из них. Давайте скорее посмотрим как это применить к настоящему коду, а не книгам.
Грубо говоря, существует несколько «контрольных» точек, которые могут нам помочь определить большую
1. Если код не оперирует входными данными, это
2. Если код итерируется по данным, это
3. Два вложенных цикла, каждый из которых проходит по входным данным, дают сложность
4. Простой вызов функции не считается отдельным шагом, считаем только шаги внутри функции.
5. Если в коде есть конструкция «разделяй и властвуй», это
6. Если «разделяй и властвуй» выполняется для каждого элемента во входных данных, это
7. Если код проходит по каждой возможной комбинации значений в
8. Если рассматриваются все возможные перестановки значений в данных, это
9. Если код предполагает сортировку данных, это будет как минимум
В целом, это хорошие ориентиры, но они не заменяют фактический анализ кода (чем мы, кстати, и займемся в заключительном посте по сложности алгоритмов). И, конечно же, напоминаем,
❓Уже зная некоторые флаги, как вы думаете, какая сложность у этих методов python?
- .append()
- .insert()
- .remove()
- .sort()
- цикл for
#сложность_алгоритмов
Из предыдущих постов мы уже знаем, как работает
O(1), O(log n), O(n), если хотите освежить память, можете вернуться к посту.А сегодня поговорим про логарифмическую сложность, квадратичную, экспоненциальную и другие типы.
🟢 Сложность O(n log n)
Фактически, все эффективные алгоритмы сортировки представляют собой O(n log n) сложность: сортировка слиянием (merge), пирамидальная сортировка (heap), быстрая сортировка, а еще Timsort (изобретенный Тимом Питерсом алгоритм, который используется методом
sort() в Python). Например, отсортировать
n книг в алфавитном порядке, как раз, представляет O(n log n) сложность.🔵 Сложность O(n^2)
Если требуется найти повторяющиеся книги на несортированной полке, это уже квадратичная сложность. Например, на полке стоят 100 несортированных книг, мы берем одну и ищем дубли среди остальных 99, потом берём другую и снова проверяем оставшиеся. Очень затратно: проверка 100 книг займёт 100 × 100, или 10 000 шагов, причем проверка 200 займёт уже 40 000 шагов - в четыре раза больше.
В реальном мире, именно для этого нам необходимо знание
BIG O. Чтобы не писать алгоритм O(n^2), когда можно было написать O(n log n) или O(n).Итак, остались те, чьи имена нельзя произносить: экспоненциальная
O(2^n) и факториальная сложность O(n!). 🟣 Сложность O(2^n)
Допустим, на полке 2 книги, и мы будем собирать все возможные комбинации книг: первая комбинация - пустая полка, вторая - книга A, третья - книга B и последняя - обе книги на полке. Для 3 книг получим уже 8 комбинаций. Так вот, это - экспоненциальный алгоритм. Причем, обратите внимание, нас интересуют не перестановки, а только комбинации.
🔴 Сложность O(n!)
Перестановки, как раз, будут отвечать за факториальную сложность: если у нас на полке
3 книги, все варианты перестановок - 3!. И оба этих алгоритма крайне плохо масштабируются: даже для малых
n они быстро становятся невыполнимыми за разумное время.💡 Наконец переходим от теории к практике!
Что из себя представляет каждый из алгоритмов мы рассмотрели, практически, под лупой. Мы также понимаем, как увеличение входных данных (количества книг) повлияет на каждый из них. Давайте скорее посмотрим как это применить к настоящему коду, а не книгам.
Грубо говоря, существует несколько «контрольных» точек, которые могут нам помочь определить большую
О. Учитывая, что n - это размер входных данных, можно сказать:1. Если код не оперирует входными данными, это
O(1).2. Если код итерируется по данным, это
O(n).3. Два вложенных цикла, каждый из которых проходит по входным данным, дают сложность
O(n^2).4. Простой вызов функции не считается отдельным шагом, считаем только шаги внутри функции.
5. Если в коде есть конструкция «разделяй и властвуй», это
O(log n).6. Если «разделяй и властвуй» выполняется для каждого элемента во входных данных, это
O(n log n).7. Если код проходит по каждой возможной комбинации значений в
n данных, это O(2^n) или другая экспоненциальная сложность (3^n, 4^n…).8. Если рассматриваются все возможные перестановки значений в данных, это
O(n!).9. Если код предполагает сортировку данных, это будет как минимум
O(n log n).В целом, это хорошие ориентиры, но они не заменяют фактический анализ кода (чем мы, кстати, и займемся в заключительном посте по сложности алгоритмов). И, конечно же, напоминаем,
О - нотация сообщает нам о том, насколько сильно усложняется процесс вычисления при увеличении входных данных. И ни в коем случае не выносит заключений о том, является ли код быстрым или медленным, эффективным или нет.❓Уже зная некоторые флаги, как вы думаете, какая сложность у этих методов python?
- .append()
- .insert()
- .remove()
- .sort()
- цикл for
#сложность_алгоритмов
🔥8👍3😁1
🔥 Почему to_char в SQL дал неправильный результат?
Лучшие генераторы для постов - наши студены! Недавно потупил вопрос, которым однозначно стоит поделиться с вами. Один студент работал над задачей, которая предполагает извлечение процента в заданном формате. Звучит легко, но все стало сильно сложнее, когда жажда знаний привела его к двум способам решения.
Получилось два варианта:
- Первый - concat -
Результат получился вроде бы одинаковым (см. под постом). Но при этом первое решение принималось, а второе - нет.
🤔 Есть идеи в чем дело?
Давайте разберемся вместе.
В первом методе сомнений нет, простой конкатенацией формат приводится к необходимому. А вот со вторым уже интереснее! Нужный шаблон заполнения
Секрет здесь в том, что
Так что же, смириться и не использовать
⁉️ Как исправить код, чтобы он заработал верно?
У
💡 Вообще, очень интересная штука эти модификаторы. Вы знали, например, что аналогично можно добавить
Думаем, урок здесь ясен: даже небольшие технические детали могут сильно влиять на ваши вычисления. Так что, будьте любознательны и не бойтесь обращаться к документации. И если у вас когда-нибудь возникнет подобный вопрос, не стесняйтесь задавать нам в чат - мы любим головоломки!
#sql
Лучшие генераторы для постов - наши студены! Недавно потупил вопрос, которым однозначно стоит поделиться с вами. Один студент работал над задачей, которая предполагает извлечение процента в заданном формате. Звучит легко, но все стало сильно сложнее, когда жажда знаний привела его к двум способам решения.
Получилось два варианта:
- Первый - concat -
'+' || ROUND (price * 1.0, 2) || '%') orders_increase
- Второй - to_char - to_char((price * 1.0),'S9990D00%’) orders_increase2
❗️Они, конечно, немного изменены, чтобы не спойлерить решение, но отражают саму проблему.Результат получился вроде бы одинаковым (см. под постом). Но при этом первое решение принималось, а второе - нет.
🤔 Есть идеи в чем дело?
Давайте разберемся вместе.
В первом методе сомнений нет, простой конкатенацией формат приводится к необходимому. А вот со вторым уже интереснее! Нужный шаблон заполнения
'S9990D00%' в to_char передали, а все равно решение не принимается.Секрет здесь в том, что
to_char дополняет строку пустыми заполнениями (пробелами) так, чтобы результат имел фиксированную ширину. Вы же заметили, что решения, по сути, различает только выравнивание? Это и есть то самое заполнение пробелами. Отсюда и несоответствие эталонному решению. Так что же, смириться и не использовать
to_char? Ну уж нет, так просто мы не сдадимся!⁉️ Как исправить код, чтобы он заработал верно?
У
to_char есть такая деталь, как модификаторы шаблонов, почитать можно тут. Они применяются, чтобы изменить поведение кода. И среди этих модификаторов нашлась такая приставка - FM, которая подавляет пустые заполнения, она передается прямо в шаблон - 'FMS9990D00%' И буквально двумя буквами мы сделали так, что код был принят!💡 Вообще, очень интересная штука эти модификаторы. Вы знали, например, что аналогично можно добавить
th и вы получите окончание порядкового числительного?Думаем, урок здесь ясен: даже небольшие технические детали могут сильно влиять на ваши вычисления. Так что, будьте любознательны и не бойтесь обращаться к документации. И если у вас когда-нибудь возникнет подобный вопрос, не стесняйтесь задавать нам в чат - мы любим головоломки!
#sql
🔥9👍4🤩1
🔥 Сценарии использования NULLIF
Вас когда-нибудь спрашивали на собеседовании о функции
В гайдах к собеседованиям куда чаще встречаются джоины и первичный ключ, а
Что такое NULLIF и как это использовать?
Пожалуй, самое полезное, что можно сделать, используя
Это один из самых распространенных вариантов использования. Например, если вы пытаетесь поделить один столбец на другой, и есть вероятность, что во втором столбце (делителе) могут оказаться нули - оберните второй столбец в
🟢 Поиск среднего значения
Такая схема будет полезна и при других вычислениях, например среднего значения. Опять же, если есть шанс, что в столбце, по которому считаем среднее могут оказаться нули, которые не должны влиять на результат - поможет
Например дана такая таблица:
Другой вариант использования
💡 В следующий раз, когда вы будете работать над проектом, попробуйте найти, где бы вы могли использовать
#sql
Вас когда-нибудь спрашивали на собеседовании о функции
NULLIF?В гайдах к собеседованиям куда чаще встречаются джоины и первичный ключ, а
NULLIF опускают. Хотя зря! NULLIF, на самом деле - мощный инструмент, который можно использовать в разных ситуациях, чтобы повысить надежность ваших запросов. Что такое NULLIF и как это использовать?
NULLIF - это функция, которая принимает два аргумента и возвращает NULL, если аргументы равны, в противном случае она возвращает первый аргумент. Синтаксис выглядит следующим образом:NULLIF(выражение 1, выражение 2)
🔵 Деление на нольПожалуй, самое полезное, что можно сделать, используя
NULLIF - пресечь ошибку деления на ноль.Это один из самых распространенных вариантов использования. Например, если вы пытаетесь поделить один столбец на другой, и есть вероятность, что во втором столбце (делителе) могут оказаться нули - оберните второй столбец в
NULLIF и вы не получите ошибок.SELECT column1/NULLIF(column2, 0)То есть, когда значение второго столбца равно 0 (аргументы в
FROM table1
NULLIF равны), вернется NULL, а не ZeroDivisionError.🟢 Поиск среднего значения
Такая схема будет полезна и при других вычислениях, например среднего значения. Опять же, если есть шанс, что в столбце, по которому считаем среднее могут оказаться нули, которые не должны влиять на результат - поможет
NULLIF.Например дана такая таблица:
| column1 | column2 |Выполнив:
|---------|---------|
| 0 | a |
| 7 | a |
SELECT column2, AVG(column1)Получим:
FROM table1
GROUP BY column2;
| column2 | avg |А с использованием
|---------|-----|
| a | 3.5 |
NULLIF получим другой результат:SELECT column2, AVG(NULLIF(column1, 0))🟣 Преобразование пустых строк
FROM table1
GROUP BY column2;
| column2 | avg |
|---------|-----|
| a | 7 |
Другой вариант использования
NULLIF - преобразование пустых строк в NULL. Например, в таблице некоторые столбцы содержат пустые строки, которые необходимо трактовать как NULL - идеально подходящая ситуация для NULLIF:SELECT NULLIF(column1, '') FROM table1;
Получим NULL, если столбец 1 содержит пустую строку, что эффективно обработает все пустые строки.💡 В следующий раз, когда вы будете работать над проектом, попробуйте найти, где бы вы могли использовать
NULLIF и убедитесь, как он легко поможет решать сложные задачи и избегать больших CASE/WHEN конструкций. Кстати говоря, NULLIF это тот же CASE/WHEN, так что, возможно, стоит провести ревизию старых проектов и увидеть потенциальные «use» кейсы. Если вы и раньше использовали NULLIF, расскажите, в каких интересных задачах он вам пригодился?#sql
👍26🔥15❤2
🔥 Пишем генератор логинов на Python
🔍 Вы когда-нибудь задумывались, как создаются уникальные случайные строки символов, которые мы видим в логинах на сайтах и приложениях?
Вроде этих: 4W008LL, UOJ97HT и тд.
Это выглядит несложно, но вы смогли бы сейчас написать скрипт на питоне, который генерировал бы подобную строку? Давайте сделаем это вместе! Сможете использовать его для различных целей, возможно даже, для вашего сайта. 😉
Итак, сталкивались ли вы раньше с модулями
🔵 Первый вариант
-
- Соединяем их, и с помощью
- И, конечно, используем цикл, для получения
🟢 Второй вариант
🤔 Попробуем еще один вариант! Что, если мы хотим персонализировать логин для пользователя так, чтобы он состоял из первой буквы его имени, нескольких букв фамилии и случайной строки символов?
На самом деле, самая сложная часть работы уже сделана:
#python
🔍 Вы когда-нибудь задумывались, как создаются уникальные случайные строки символов, которые мы видим в логинах на сайтах и приложениях?
Вроде этих: 4W008LL, UOJ97HT и тд.
Это выглядит несложно, но вы смогли бы сейчас написать скрипт на питоне, который генерировал бы подобную строку? Давайте сделаем это вместе! Сможете использовать его для различных целей, возможно даже, для вашего сайта. 😉
Итак, сталкивались ли вы раньше с модулями
string и random? Они как раз и помогают генерировать случайные строки символов, и если постараться можно справиться всего одной строкой!🔵 Первый вариант
import string-
import random
''.join(random.choice(
string.ascii_uppercase +
string.digits)
for _ in range(N))
string.ascii_uppercase - строка, содержащая все заглавные буквы английского алфавита (ABCDEFGHIJKLMNOPQRSTUVWXYZ)-
string.digits - это строка, содержащая все цифры (0123456789).- Соединяем их, и с помощью
random.choice выбираем случайный символ.- И, конечно, используем цикл, для получения
N знаков в наш логин, и все это соединяем с помощью ''.join.🟢 Второй вариант
🤔 Попробуем еще один вариант! Что, если мы хотим персонализировать логин для пользователя так, чтобы он состоял из первой буквы его имени, нескольких букв фамилии и случайной строки символов?
На самом деле, самая сложная часть работы уже сделана:
import stringПопробуем:
import random
def generator(first_name,
last_name, size=6):
# Удаляем пробелы из имени
и фамилии и преобразуем
их в верхний регистр
first_name =
first_name.strip().upper()
last_name =
last_name.strip().upper()
# Эта часть кода у нас уже
была
chars =
string.ascii_uppercase +
string.digits
random_string = ''.join(
random.choice(chars)
for _ in range(size))
# Просто соединяем
все части
login_id = first_name[0] +
last_name[:5] +
random_string
return login_id
generator('Jon', 'Snow', 5)
>> JSNOWZKHKY
Круто, правда? Теперь вы можете создавать уникальные логины для пользователей всего за несколько строк кода! 😉#python
👍11🔥3
🔥 4 разных решения бизнес-задачи c SQL
Бизнесу часто приходится анализировать данные о продажах, чтобы понимать, какие продукты или какой реселлер приносят наибольшую прибыль. Однако нужно помнить и о тех, кто не приносит продаж вовсе. Это, возможно, даже важнее 😄
Сегодня мы рассмотрим 4 способа решения такой задачи.
Дано: у нас есть две таблицы:
❓Итак, мы хотим найти продавцов, которые не приносили нам никакого дохода вообще, то есть не содержатся в таблице
У нас, есть как минимум 4 надежных способа решения этой задачи! Мы будем использовать PostgreSQL, но они также будут работать и для других СУБД, так как являются стандартными.
🔴 LEFT JOIN / IS NULL
Наверняка, это первая идея для решения такой задачи. В зависимости от таблиц, этот метод может работать достаточно быстро.
А этот метод вряд ли первым придет в голову, хотя зачастую он имеет преимущество в скорости для PostgreSQl.
🟢 EXCEPT
Редко используемый, но один из самых коротких и простых вариантов. Хотя, если запрос станет сложнее, его не так легко будет интегрировать.
Будет работать без проблем в том случае, если в таблицах нет
#sql
Бизнесу часто приходится анализировать данные о продажах, чтобы понимать, какие продукты или какой реселлер приносят наибольшую прибыль. Однако нужно помнить и о тех, кто не приносит продаж вовсе. Это, возможно, даже важнее 😄
Сегодня мы рассмотрим 4 способа решения такой задачи.
Дано: у нас есть две таблицы:
Resellers (id, address) и Proceeds (id, revenue, period). В первой, соответственно, хранятся все наши продавцы, во второй - некоторая форма отчетности (id продавца, доход за период, период), причем эти отчеты формируются не на регулярной основе, а по факту получения прибыли.❓Итак, мы хотим найти продавцов, которые не приносили нам никакого дохода вообще, то есть не содержатся в таблице
proceeds. Как бы вы с этим справились?У нас, есть как минимум 4 надежных способа решения этой задачи! Мы будем использовать PostgreSQL, но они также будут работать и для других СУБД, так как являются стандартными.
🔴 LEFT JOIN / IS NULL
Наверняка, это первая идея для решения такой задачи. В зависимости от таблиц, этот метод может работать достаточно быстро.
SELECT r.id🔵 NOT EXISTS
FROM resellers r
LEFT JOIN proceeds p USING (id)
WHERE p.id IS NULL;
А этот метод вряд ли первым придет в голову, хотя зачастую он имеет преимущество в скорости для PostgreSQl.
SELECT idОбратите внимание, что PostgreSQL позволяет оставить пустым поле
FROM resellers r
WHERE NOT EXISTS (
SELECT
FROM proceeds
WHERE id = r.id
);
select в подзапросе.🟢 EXCEPT
Редко используемый, но один из самых коротких и простых вариантов. Хотя, если запрос станет сложнее, его не так легко будет интегрировать.
SELECT id🟡 NOT IN
FROM resellers
EXCEPT ALL
SELECT id
FROM proceeds;
Будет работать без проблем в том случае, если в таблицах нет
NULL значений. То есть, если одно из значений будет NULL, NOT IN вернет NULL, в то время как NOT EXISTS вернет TRUE. В нашем случае, конечно, id не может быть NULL, но это важно понимать для других кейсов.SELECT id✅ Мы убедились, что в SQL существует несколько подходов к одной проблеме. Но при этом очень легко заработать привычку использовать одни и те же методы снова и снова. Здесь важно сохранять здоровое любопытство и рассматривать новые решения. Поэтому, если вы вдруг застряли в рутине
FROM resellers
WHERE id NOT IN (
SELECT DISTINCT id
FROM proceeds
);
INNER JOINов, не бойтесь отвлечься и попробовать что-то новое. Может, вы найдете новое, более эффективное решение!#sql
🔥16👍6❤2
🔥 ARPU и ARPPU спешат бизнесу на помощь!
Хотите повысить доходы своего бизнеса, но не уверены, как измерять эффективность монетизации своих пользователей? Мы, с ARPU и ARPPU спешим к вам на помощь.
🔵 Что такое ARPU?
ARPU (Average revenue per user) или средний доход на пользователя - это показатель, который измеряет средний доход, генерируемый каждым активным пользователем.
Как рассчитать?
ARPU рассчитывается как сумма общего дохода, деленная на количество активных пользователей. Высокий ARPU - показатель успешной монетизации.
🔴 Что такое ARPPU?
ARPPU (Average revenue per paying user) - доход, генерируемый одним платящим пользователем в течение некоторого периода. Платящие пользователи - это те, кто платит деньги (подписываясь, совершая покупки, либо оплачивая другие услуги). Этот показатель не учитывает тех пользователей, которые активно не тратят деньги в течение пользования (например, тех, кто приносит доход за счет рекламы).
Допустим, у вас
🟢 Для чего используется APRU?
ARPU - отличный показатель качества дохода, который вы получаете от клиентов.
Кроме того, средний размер сделки позволяет вам разделить вашу клиентскую базу на сегменты и проанализировать, как работает каждый сегмент. Или разделить клиентов по каналу, через который они пришли, и сравнить средний доход, полученный с клиента в каждом сегменте.
🟣 Почему важен ARPPU?
Этот показатель дает понять, сколько готов платить лояльный пользователь. Другими словами, ARPPU показывает вам, работают ли ваши усилия по привлечению и получаете ли вы достаточный доход от своих самых лояльных клиентов.
Кроме того, ARPPU может помочь определить, эффективно ли ценообразование. Легче принимать решения о доходах, рассматривая клиентов, тратящих больше всего, чем учитывая и тех, кто, вероятно, будет использовать только бесплатную часть, независимо от ваших усилий и рекламы.
❓ В чем разница?
Несмотря на то, что доходы от платящих пользователей могут быть очень высокими, конверсия в платящих пользователей, как правило, очень низкая, обычно всего несколько процентов. Это означает, что монетизация рекламы сегодня становится все более важным источником дохода, дополняя доход от платящих пользователей и монетизируя не платящих через рекламу.
📈 На Симуляторе "Аналитик данных" мы подробно разбираем продуктовые метрики: какие бывают, как их считать с помощью SQL и Python и как интерпретировать результаты. Попробуйте демо-главу!
#продуктовые_метрики
Хотите повысить доходы своего бизнеса, но не уверены, как измерять эффективность монетизации своих пользователей? Мы, с ARPU и ARPPU спешим к вам на помощь.
🔵 Что такое ARPU?
ARPU (Average revenue per user) или средний доход на пользователя - это показатель, который измеряет средний доход, генерируемый каждым активным пользователем.
Как рассчитать?
ARPU рассчитывается как сумма общего дохода, деленная на количество активных пользователей. Высокий ARPU - показатель успешной монетизации.
ARPU = общий доход / количество активных пользователей
Важно: Если ваш бизнес предполагает некоторый бесплатный период, обязательно рассматривайте и ARPPU - средний доход на платящего пользователя. Поскольку в таких случаях показатели могут достаточно серьезно отличаться.🔴 Что такое ARPPU?
ARPPU (Average revenue per paying user) - доход, генерируемый одним платящим пользователем в течение некоторого периода. Платящие пользователи - это те, кто платит деньги (подписываясь, совершая покупки, либо оплачивая другие услуги). Этот показатель не учитывает тех пользователей, которые активно не тратят деньги в течение пользования (например, тех, кто приносит доход за счет рекламы).
ARPPU = общий доход / количество платящих пользователей
✏️ ПримерДопустим, у вас
1000 пользователей, и 20 из них платят. Ваш общий ежемесячный доход составляет 2000 долларов. Таким образом, ARPU в месяц равен 2000/1000 = 2 (один активный пользователь приносит вам в среднем 2 доллара в месяц). В то же время ARPPU будет равен 2000/20 = 100.🟢 Для чего используется APRU?
ARPU - отличный показатель качества дохода, который вы получаете от клиентов.
Кроме того, средний размер сделки позволяет вам разделить вашу клиентскую базу на сегменты и проанализировать, как работает каждый сегмент. Или разделить клиентов по каналу, через который они пришли, и сравнить средний доход, полученный с клиента в каждом сегменте.
🟣 Почему важен ARPPU?
Этот показатель дает понять, сколько готов платить лояльный пользователь. Другими словами, ARPPU показывает вам, работают ли ваши усилия по привлечению и получаете ли вы достаточный доход от своих самых лояльных клиентов.
Кроме того, ARPPU может помочь определить, эффективно ли ценообразование. Легче принимать решения о доходах, рассматривая клиентов, тратящих больше всего, чем учитывая и тех, кто, вероятно, будет использовать только бесплатную часть, независимо от ваших усилий и рекламы.
❓ В чем разница?
Несмотря на то, что доходы от платящих пользователей могут быть очень высокими, конверсия в платящих пользователей, как правило, очень низкая, обычно всего несколько процентов. Это означает, что монетизация рекламы сегодня становится все более важным источником дохода, дополняя доход от платящих пользователей и монетизируя не платящих через рекламу.
📈 На Симуляторе "Аналитик данных" мы подробно разбираем продуктовые метрики: какие бывают, как их считать с помощью SQL и Python и как интерпретировать результаты. Попробуйте демо-главу!
#продуктовые_метрики
🔥10👍9
🔥 Вносим ясность в визуализацию Python
Те, кто часто сталкиваются с визуализацией данных, наверняка поймут нашу боль! Как же иногда бывает непросто передать нужный message всего одним графиком. А дополнение другими - только ухудшает ситуацию.
💡 Есть решение!
Замечательный способ дать дополнительную информацию - добавить текстовые аннотации прямо на график.
Функция
Ее не так активно рассматривают в курсах, если вообще рассматривают, поэтому показываем:
-
-
Это очень простой пример, поэтому сделаем кое-что посложнее. Добавим аннотации на график индекса S&P 500.
Смотрите в карточках под постом, что у нас получилось!
💥 Используйте annotate, чтобы добавить контекст вашим визуализациям. Это поможет точнее отображать ваши выводы!
#python #visualization
Те, кто часто сталкиваются с визуализацией данных, наверняка поймут нашу боль! Как же иногда бывает непросто передать нужный message всего одним графиком. А дополнение другими - только ухудшает ситуацию.
💡 Есть решение!
Замечательный способ дать дополнительную информацию - добавить текстовые аннотации прямо на график.
Функция
annotate() библиотеки matplotlib позволяет добавить *пояснительный* текст на график, фокусируя зрителя на конкретных деталях и контролируя его внимание.Ее не так активно рассматривают в курсах, если вообще рассматривают, поэтому показываем:
import matplotlib.pyplot as pltСинтаксис:
# создаем самый элементарный график
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
plt.plot(x, y)
# добавляем аннотацию
plt.annotate('Max value', xy=(5, 10), xytext=(4, 8),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
plt.annotate(text, xy, xytext)
- text - текст аннотации-
xy - позиция на графике, в которую будет передан текст (если не задавать параметр xytext)-
xytext - вторая позиция расположения текста (если она задана, то текст будет расположен в xytext, а в позицию xy будет проведена указательная стрелка, параметры которой можно задать в arrowpops)Это очень простой пример, поэтому сделаем кое-что посложнее. Добавим аннотации на график индекса S&P 500.
Смотрите в карточках под постом, что у нас получилось!
💥 Используйте annotate, чтобы добавить контекст вашим визуализациям. Это поможет точнее отображать ваши выводы!
#python #visualization
🔥7❤5