Don Python [DATA SCIENCE]
71 subscribers
6 photos
1 file
19 links
Путь python разработчика после 30. Знания, обсуждения, книги, rock & roll
Download Telegram
Channel name was changed to «Don Python»
Если в условии нам нужно поймать промежуток от N до M значения, вместо размашистого:
if credit_rating > 120 and credit_rating <= 60:

можно написать:
if 60 <= credit_rating < 120:
Если вы работаете в PyCharm, то по неопытности можете столкнуться с таким предупреждением:

Multi-step list initialization can be replaced with a list literal


Дословный перевод выглядит так:

Многоступенчатая инициализация списка может быть заменена литералом списка


Проще (но длиннее) говоря, вы добавляете что то в список сразу после его инициализации, хотя можно сразу создать список не используя дополнительных элементов.

Рассмотрим два примера.

Пример попроще:

food = ['pizza', 'hamburger', 'hotdog', 'spaghetti']
food.append('ice cream')


В этом случае можно 'ice cream' сразу объявить в списке:

food = ['pizza', 'hamburger', 'hotdog', 'spaghetti', 'ice cream']


Либо если вы ранее как то изменяли список, то метод append() будет оправдан:

food = ['pizza', 'hamburger', 'hotdog', 'spaghetti']
food.remove('hotdog')
food.append('ice cream')


Пример посложнее:

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for i in range(5):
cache = [x[0], x[1], x[2]]
cache.append(0 if sum(cache) == 0 else 1)


Здесь можно не сразу догадаться как улучшить код, особенно на ранних этапах изучения. Например мы не сможем обратиться к cashe внутри списка. Но если немного углубиться в синтаксис, то мы узнаем что [x[0], x[1], x[2]] это тоже что и x[:3]. Следуя этому правилу, можно сократить код на одну строку:

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for i in range(5):
cache = x[:3] + [0 if sum(x[:3]) == 0 else 1]


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

Предположим что в файле main.py есть такая функция:

def test():
print('I am a function!')


Мы хотим импортировать ее в файле hello.py из модуля 00_numbers:

from 00_numbers.main import test


Получаем ошибку:

SyntaxError: invalid decimal literal


Для решения проблемы нам нужно воспользоваться стандартной библиотекой:

import importlib
main = importlib.import_module('00_numbers.main')

main.test() # output: I am a function!


Good coding 👨🏻‍💻
🔍 Поиск среднего значения

Давайте представим, что у нас есть три случайных числа и нам нужно вывести то число, которое больше одного, но меньше второго — n1 < n2 < n3.

Можно это сделать с помощью условий:

v1 = int(input())
v2 = int(input())
v3 = int(input())

if (v2 < v1 < v3) or (v2 > v1 > v3):
print(v1)
elif (v1 < v2 < v3) or (v1 > v2 > v3):
print(v2)
else:
print(v3)


А можно упростить себе жизнь:

weights = sorted([v1, v2, v3])
print(weights[1])


Good coding 👨🏻‍💻

#sorted #list
🎵 Музыкальная задачка

Задача о которой идет речь тут.

Есть у нас такой код:

a_minor_count = 0 
for tone in accented_tones:
if tone in a_minor_main_tones:
a_minor_count += 1


А вот это оказывается по смыслу такой же код:

a_minor_count = sum(1 for tone in accented_tones if tone in a_minor_main_tones)


Всё было понятно, кроме того, где хранится и как суммируется единичка с другой единичкой. А получается, что каждая итерация, которая возвращает единицу, по сути генерирует аргумент функции sum(). То есть если цикл вернул 4 единицы, то это эквивалентно записи sum(1, 1, 1, 1).

Good coding 👨🏻‍💻

#for #sum
🔄 Числа Фибоначчи

У skillbox есть отличная статья на эту тему, но я приведу только определение:

Числа Фибоначчиэто последовательность чисел, которые задаются по определённому правилу. Оно звучит так: каждое следующее число равно сумме двух предыдущих. Первые два числа заданы сразу и равны 0 и 1.


Последовательность Фибоначчи задаётся линейным рекуррентным соотношением, которое можно выразить формулой:

F0 = 0, F1 = 1, Fn = Fn-1 + Fn-2

Можно записать эту формулу в виде функции:

def fibonacci(n):
if n == 0:
return 0
elif n == 1 or n == -1:
return 1
elif n < 0:
return int((-1)**(n+1) * fibonacci(-n))
else:
return fibonacci(n - 1) + fibonacci(n - 2)

print(f'Result: {fibonacci(4)}')


Функция простая и может стать отправной точкой для изучения возможностей рекурсии в программировании.

Good coding 👨🏻‍💻

#recursion #fibonacci
❤‍🔥1
📕 Последовательности символов в строке

Я решаю задачки на сайте DMOJ и одна задача поставила меня в небольшой тупик.
Главная трудность заключалась в написании небольшой функции, которая принимала строку без пробелов, а возвращала бы строку, где каждая непрерывная последовательность одинаковых символов была бы представлена в следующем виде: 3 p, где цифра 3 обозначает сколько символов p было в последовательности. Сейчас будет понятней:

Строка входа

input = 'pppqqq++++'


Строка выхода

output = '3 p 3 q 4 +'


В итоге как с помощью python из строки input получить строку output?

Решение кроется в 14 строках:

def compress_string(string):
compressed = []
count = 1

for i in range(1, len(string)):
if string[i] == string[i - 1]:
count += 1
else:
compressed.append(f"{count}({string[i - 1]})")
count = 1
compressed.append(f"{count}({string[-1]})")
return " ".join(compressed)

print(compress_string('pppqqq++++'))


Good coding 🧑‍💻

#problem #string #algorithm
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🤷‍♂️ Копирование списка

У нас есть простой список: x = [1, 2, 3, 4, 5, 6, 7]


Мы без проблем можем изменить любой элемент списка по индексу:

x[0] = 99  # x == [99, 2, 3, 4, 5, 6, 7]


Рассмотрим следующий код:

x = [1, 2, 3, 4, 5, 6, 7]

y = x

x[0] = 99

print(y) # y == [99, 2, 3, 4, 5, 6, 7]


Следуя обычной логике, можно предположить что 'y' должен содержать в себе изначальное состояние списка 'x'. Но в python, если мы напрямую присваиваем переменной список без дополнительных манипуляций, то эта переменная не получает копию списка, она получает ссылку на присваиваемый список.

Что бы копировать список, можно в момент присваиваний сделать срез для списка 'x', вот так: y = x[:]. Тогда 'y' получит копию списка 'x', а не ссылку на него.

Good coding 🧑‍💻

#list #python #5min_py
Please open Telegram to view this post
VIEW IN TELEGRAM
11
🌡 List comprehension

Или генератор списка на русском.

В одной задаче нужно было создавать и наполнять список получив предварительно каждое значение из пользовательского ввода ( input ). Моё решение выглядело так:

villages_count = int(input())

villages = []
for _ in range(villages_count):
village = int(input())
villages.append(village)


Но пять строк магическим образом могут превратиться в две:

villages_count = int(input())
villages = [int(input()) for _ in range(villages_count)]


Подробнее о теме можно почитать тут — Руководство по использованию list comprehension

Good coding 🧑‍💻

#list #python #5min_py
Please open Telegram to view this post
VIEW IN TELEGRAM
11
[PROBLEM] Basketball game

Иногда решить задачу легче, чем ее описать.

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

Сложность для junior: 7 / 10

Задача с решением на русском здесь

———

Good coding 🧑‍💻

#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
11
⬆️ [INFO] Надо добавить элемент в произвольную позицию списка

🚩 Вариант

Метод insert(). Работает он просто: первым параметром передаём индекс, по которому будет находится новый элемент, а вторым параметром передаём сам элемент.

my_list = [1, 2, 3, 5]
my_list.insert(3, 4)
print(my_list)

# output [1, 2, 3, 4, 5]


Если следовать простой логике, то можно подумать, что число 4 должно заменить число 5. Но на самом деле, если по указанному индексу находится элемент, то индекс этого элемента и всех элементов после него увеличивается на 1. В наше случае индекс числа 5 становится 4, а третий индекс занимает число 4.

🚩 Вариант

Мы можем добавить элемент с помощью среза.

my_list = [1, 2, 3, 5]
my_list[3:3] = [4]
print(my_list)

# output [1, 2, 3, 4, 5]


Что бы это работало, нужно соблюсти два условия:

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

Операции со срезами могут изменять последовательность в списке, но только при условии, что мы присваиваем другой итерируемый объект, такой как список. Срез возвращает не один элемент, а последовательность элементов (список), и, соответственно, при присвоении Python ожидает последовательность в качестве значения.


Первый вариант более академичный, второй лаконичный, но любой из них правильный.

———

Good coding 🧑‍💻

#python #5min_py #list
Please open Telegram to view this post
VIEW IN TELEGRAM
11
[PROBLEM] Mountain streams

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

Сложность для junior: 5 / 10

Задача с решением на русском здесь

* Прежде чем смотреть готовое решение,желательно потратить 2-3 часа на самостоятельные попытки. И если не получится, то переходить к анализу ответа.

———

Good coding 🧑‍💻

#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
11
⬆️ [INFO] Функция map()

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

Предположим что в ходе работы разработчик получает список чисел — numbers = [5, 5, 10, 25, 35, 70]
Что бы работать дальше с этим списком, необходимо преобразовать его в строку. Если попробовать преобразовать напрямую, то код 'упадет' с ошибкой:

numbers = [5, 5, 10, 25, 35, 70]
str_numbers = ' '.join(numbers)

# >>> TypeError: sequence item 0: expected str instance, int found


Очевидный способ решения — это пробежаться циклом for по всем элементам списка:

numbers = [5, 5, 10, 25, 35, 70]
str_streams = [str(number) for number in numbers]
string = ' '.join(str_streams)

print(string)

# >>> 5 5 10 25 35 70


Можно остановиться и на таком варианте, так как это более чем хорошее решение. Но есть более элегантный способ, мимо которого не хочется проходить.

Так как здесь затрагивается часть идеи функционального программирования, советую почитать об этом стиле на странице официального источника


Посмотрим на преобразованный код:

numbers = [5, 5, 10, 25, 35, 70]
string = ' '.join(map(str, numbers))

print(string)

# >>> 5 5 10 25 35 70


Выглядит не плохо, мы избавились от одной строки, но код стал даже более очевидным. Что в нашем случае делает map()? Буквально принимает два аргумента: функцию и итерируемый объект.

Функция
map()
применяет переданную в параметрах функцию к каждому элементу переданного в параметрах итерируемого объекта, после чего возвращает преобразованный итерируемый объект


Для этого короткого примера не потребуется развернутого объяснения. По сути, если словами выразить команду map(str, numbers), то получится: преобразуй в строку каждое число в списке numbers с помощью функции str.

[WARN] Функция передаваемая в параметрах должна передаваться без вызова, то есть без скобок. Если мы передадим и сразу вызовем функцию, то произойдет ошибка:

numbers = [5, 5, 10, 25, 35, 70]
string = ' '.join(map(str(), numbers))

print(string)

# >>> TypeError: 'str' object is not callable


Функция map позволяет делать больше, чем можно описать в посте. Предлагаю особо любопытствующим почитать long read на тему.

———

Good coding 🧑‍💻

#python #function #5min_py #map
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🤕 [SHORT] Не очевидное создание кортежа

При создании кортежа можно опустить скобки. Нужно ли? Дело каждого, но язык позволяет это сделать:

numbers = 5, 5, 10, 25, 35, 70
print(numbers)

# >>> (5, 5, 10, 25, 35, 70)


———

Good coding 🧑‍💻

#python #tuple #short
Please open Telegram to view this post
VIEW IN TELEGRAM
2
🤕 [SHORT] Оператор else для цикла

В Python блок else может использоваться не только в условных конструкциях if, но и с циклами for и while. Блок else в цикле выполняется, если цикл завершился "нормально", то есть без прерывания с помощью оператора break. Если же цикл был прерван с помощью break, блок else не выполнится. Это позволяет, например, выполнить определенный код в конце цикла, если цикл не был прерван.

for i in range(5):
if i == 3:
print("Цикл прерван на итерации:", i)
break
else:
print("Цикл завершился без прерываний")


В этом цикле блок кода после else не выполнится. Но следующий цикл "переживет" все итерации и блок else выполнится:

for i in range(5):
print("Текущая итерация:", i)
else:
print("Цикл завершился без прерываний")


———

Good coding 🧑‍💻

#python #else #for #while #short
Please open Telegram to view this post
VIEW IN TELEGRAM
2
[PROBLEM] Asya the cat is playing with boxes

Перевод и решение задачи посвящается прекрасной кошке Асе. На самом деле с коробками любит играть кот Арсений. Поэтому у Аси не нашлось фото с коробкой 🐈🐈

Сложность для junior: 4 / 10

Задача с решением на русском здесь

* Прежде чем смотреть готовое решение,желательно потратить 2-3 часа на самостоятельные попытки. И если не получится, то переходить к анализу ответа.

———

Good coding 🧑‍💻

#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
2
🤕 [SHORT] Памятка по созданию и подключению виртуального окружения

Открываем терминал в корне проекта и прописываем — python -m venv venv

— Флаг -m используется для запуска venv как исполняемого модуля.

— Первое написание venv является командой, а второе можно заменить на удобное название, под которым будет хранится директория виртуального окружения.

💻 Создание окружения в pycharm без терминала

— Проходим по пути settings - project:<your_project> - python Interpreter для открытия окна с настройками виртуального окружения

— Нажимаем справа сверху add Interpreter и выбираем add local Interpreter

— Настройте интерпретатор и нажмите OK. По сути в Base Interpreter просто выберите доступный интерпретатор и это все настройки

🖥 Активация

Что бы активировать окружение на windows введите .\venv\Scripts\activate, где venv название директории с виртуальным окружением.

Для активации на mac и linux введите source venv/bin/activate

Если вы используете git bash, то команда активации будет следующей — source venv/Scripts/activate


Что бы отключить окружение введите deactivate

———

Good coding 🧑‍💻

#python #memo #venv
Please open Telegram to view this post
VIEW IN TELEGRAM
2
[PROBLEM] Big wash

Задача о том, как программисты добывают себе одежду 🛒

Сложность для junior: 7 / 10

Задача с решением на русском здесь

* Прежде чем смотреть готовое решение,желательно потратить 2-3 часа на самостоятельные попытки. И если не получится, то переходить к анализу ответа.

———

Good coding 🧑‍💻

#python #problem #list
Please open Telegram to view this post
VIEW IN TELEGRAM
3