14 subscribers
38 photos
3 files
18 links
Download Telegram
.py
#教え Видео 7/22 30:00 -> 50:00 # Итератеры это механизм помогающий последовательно проходить объектам последовательностям (sequences-str,list,set) по сути любой объект можно следать итерируемым, если в его содержимом есть что перебирать, для этого нужно…
#value Основные моменты Pytup 2024: итоги года Часть I

## Тренды

### 1) Саб-интерпретаторы в Python

В Python есть такая механика, как GIL (Global Interpreter Lock) — в моменте может работать только один поток обработки Python, доступ к объектам также возможен только из одного потока. Это безопасно, но узко для производительности.

Для решения этой проблемы используются обсуждаемые и экспериментируемые саб-интерпретаторы.

Основные моменты о саб-интерпретаторах:

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

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

- Многопоточность: Саб-интерпретаторы могут обеспечить более эффективное использование памяти и CPU в многопоточных приложениях.

### 2) Статические атрибуты

В контексте Python «статические атрибуты» (или «статические свойства») относятся к атрибутам, которые принадлежат классу, а не его экземплярам. Это означает, что статические атрибуты создаются на уровне класса и могут быть доступны через сам класс, а не через экземпляр.

По сути, они помогают решать проблему слишком большой нагруженности полей класса и выделения памяти под них. Как именно?

Когда класс имеет множество экземпляров (объектов), каждый экземпляр в памяти будет хранить свои собственные копии всех атрибутов, определённых в классе, включая переменные экземпляра. Это может привести к значительным расходам памяти, особенно если эти атрибуты имеют большие объёмы данных или если экземпляров много.
#value Основные моменты Pytup 2024: итоги года Часть II

## 3) Обновления в Python 3.13

### Поддержка Android и iOS

В Python платформы распределяются по приоритету поддержки:

1. Основные и наиболее распространенные версии Python и платформы:
Windows, macOS, Linux.

2. Python 2.7, FreeBSD или некоторые дистрибутивы Linux.

3. Платформы с ограниченной поддержкой:
Сильно устаревшие версии Python, экзотические или со специфическими требованиями операционные системы (например, какие-то мобильные платформы или специфические встраиваемые системы).

По сути, в файлах Python устанавливаются папки, соответствующие новым платформам, и там указываются флаги для их обработки. По идее, теперь можно будет запустить Python на Android и iOS по умолчанию, а не через сторонние оболочки (если имеется Python-ядро).

## 4) RAF и линтеры

- RAF (Rapid Application Framework):
Как уже упоминалось, это концепция быстрого создания приложений с использованием фреймворков, которые упрощают процесс разработки.

- Линтеры в контексте Python:
Линтеры — это инструменты статического анализа кода, предназначенные для выявления ошибок, предупреждений и проблем в коде. В Python популярными линтерами являются:

* Pylint — мощный инструмент для проверки качества кода.
* Flake8 — объединяет функциональность PEP 8 (стилистические рекомендации для Python) и других проверок.
* Black — автоформатировщик, который следит за стилем кода.

### Связь между RAF и линтерами

1. Разработка с RAF: Если вы используете Rapid Application Framework для разработки вашего веб-приложения на Python, вы можете интегрировать линтеры в процесс разработки, чтобы соблюсти стиль кода и уменьшить количество ошибок.

2. Развёртывание на VPS: После разработки приложение можно разместить на VPS. Это позволяет вам управлять средой выполнения и более гибко настраивать сервер под ваши нужды.

3. Качество кода: При разработке приложения стоит обращать внимание на линтеры, чтобы ваш код был чистым и понятным, что особенно важно, если вы планируете далее разворачивать его на VPS и поддерживать.

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

## 5) Какие интересные open-source проекты открылись в 2024

- HTTP Client Nikwest: Новый HTTP-клиент как аналог для httpx (эти ребята однажды сломали обратную совместимость, и много кто, как я понял, погорел на этом).

- Интересный язык Glim: Как Go и Rust вместе (к Python не относится).
This media is not supported in your browser
VIEW IN TELEGRAM
#教え
Видео 7/22 50:00 -> 1:01:00

Генераторы — объекты, вырабатывающие возвращаемое значение динамически при вызове. Они хороши тем, что при выработке возвращают значение, но нигде его не хранят. Генераторы полезны, когда известно, что функция вернёт большой набор значений, который нужно прочитать только один раз.

>>>my_generator = (x*x for x in range(3)) # с помощью comprehension
>>> animals = ['cat', 'dog', 'monkey']
>>> animals
['cat', 'dog', 'monkey']
>>> def animal_generator(): # по классике
... for animal in animals:
... yield animal # вместо return
...
>>> animal_gen = animal_generator()
>>> type(animal_gen)
<class 'generator'>
>>> animal_1 = next(animal_gen) # next(вызов следующей выработки, следующего объекта)
>>> animal_1
'cat'
>>> next(animal_gen)
'dog'
>>> next(animal_gen)
'monkey'
>>> next(animal_gen) # при вызове next для закончившего выработку генератора всплывет ошибка StopIteration
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
#event Changellenge

t.me/changellenge

Рекрут форум для привлечения молодых специалистов.

В Ленинградской гостинице в Москве (Hilton) арендовали зал и разместили 12 стендов от каждой компании.

При подходе к стендам я использовал фразу:

"Привет, я Python-разработчик. Что ваша компания может мне предложить, и чем я могу быть полезен?"

Консалтинг:

Kept
Б1 — берут на стажировки с дипломом (высшее образование, 3 курс)

Банки:

Альфа-Банк — берут без вышки, но со скиллами
ВТБ — важна вышка с 3 курса
ФБК

Федеральные:

Молодёжные карьерные проекты правительства Москвы — практика

Другое:
Авито
М.Видео — берут, стажировка летом. Если подам сейчас, могут взять, потому что откликнулся одним из первых.
Марс (шоколадки)
#event Changellenge инфа от рекрутеров

При разговоре с рекрутерами показывал резюме.

По резюме стоит расписать конкретнее, чем я занимался.
Если есть цифры, то это отлично — например, "за год работы в компании восстановил и обновил 36 устаревших сервисов".
Указать конкретные рабочие кейсы.

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

На каких ресурсах искать работу:

HR-почта компании — отправлять резюме с сопроводительными письмами. Обычно такие почты можно найти на сайтах компаний, но возможно, придется брать их у разработчиков, уже работающих в них.
Телеграм и ВК компаний.
Каналы и блоги компаний. В них стоит немного поактивничать, полайкать и оставить умные комментарии (возможно, тут можно использовать селф-промо, возможно есть шанс, что тебя тоже где-то заметят).
Блог вакансий компании.
Также рекрутер ФБК говорит, что для неё важно, чтобы кандидат имел представление о конкретном бизнесе:

Читал о компании, её историю.
Знал, чем она занимается.
Знал, какие сервисы предлагает.
Осведомлён о технологиях.
#教え
Видео 7/22 50:00 -> 1:20:00

Скрипты на python
Функции можно вызывать из терминала и передавать аргументы. Например, если нужно одной командой подключиться к vpn.
#Скрипт подсчитывает количество файлов с указанным расширение по пути   
from pathlib import Path
from pprint import pprint
import sys

print(sys.argv)
try:
print()
# Создаем объект Path для указанной директории
path = Path(sys.argv[1])

file_counter = 0
files = path.iterdir()
contents = len(list(filter(lambda x: sys.argv[2] in x.suffix, files)))
# contents = [(lambda files, file_counter: file_counter += 1)()
# for item in] # Список с именами
pprint(contents)
except FileNotFoundError:
print(f"Папка '{sys.argv[1]}' не найдена.")
except Exception as e:
print(f"Произошла ошибка: {e}")
#教え
Видео 7/22 1:20:00 -> end

Задачи
# возвращает сумму цифр в числе 1 способ
def get_digit_sum(number: int) -> int:
return sum([int(str_dig) for str_dig in str(number)])


# возвращает сумму цифр в числе 2 способ

def get_digit_sum_reduce(number: int) -> int:
return reduce(lambda x, a: x + int(a), [int(i) for i in str(number)])


# находит первое число встречающееся 3 раза подряд

def get_third_entered_element(number: int) -> int:
elements_count = {}
number_generator = (x for x in enumerate(str(number)))
for pair in number_generator:
i = pair[0]
el = pair[1]
if el not in elements_count:
elements_count[el] = 0
elements_count[el] += 1
if elements_count[el] == 3:
return int(el)
return 0
#git Сброс индекса

Если git зацепил в индекс мусорные файлы типо pycache, и при изменении .gitignore из индекса это не исчезло
git rm -r --cached {название файла} # удалить из индекса но оставить в проекте
#教え
Видео 8/22 begin -> 45:00

ООП


#пример инициализации класса
class House:
term = 5 # атрибут, поле или свойство
street = 'Pushkinskaya'

# перед init зачастую не пишется но всегда происходит метод __new__
# который отвечает за выделение памяти(объявление) и возврат состояния
#def __new__(cls, *args, **kwargs):
# print("Creating instance")
# instance = super(MyClass, cls).__new__(cls)
# return instance

# метод отвечающий за инициализацию класса (заполнение)
def __init__(self, term): метод для заполнения
self.term = term

# метод класса
def get_address(self):
return f"{self.term} {self.term}"


В python все является объектами все объекты наследуются от базового класса object
#教え
Видео 8/22 45:00 -> 1:45:00

ООП - Наследование


class Table:
def __init__(self, w, l, h):
self.width = w
self.length = l
self.height = h


class KitchenTable(Table):
places: int = 1 # по умолчанию

def set_places(self, p: int):
self.places = p


class DeskTable(Table):
def get_square(self):
return self.width * self.length


# переопределение родительского метода
class ComputerTable(DeskTable):
def get_square(self, e): # новый аргумент
return self.width * self.length - e


# расширение родительского метода - не полностью переписываем, а изменяем результат
class AdminTable(DeskTable):
def get_square(self, e):
return DeskTable.get_square(self) - e


# bad
class KitchenTable(Table):
def __init__(self, w, l, h, p): # дублирование кода
self.width = w
self.length = l
self.height = h
self.places = p


# well done
class KitchenTable(Table):
def __init__(self, w, l, h, p: int):
Table.__init__(w, l, h)
self.places = p


super() позволяет обращаться к родителю класса наподобии self, его плюс в том что он *не вызывает рекурсию* (проходит по родителю 1 раз вглубь и так же название родительского класса пишется ссылкой на подобии self, а не явно как в примере выше

class Rectangle:

def __init__(self, w, l):
self.width = w
self.length = l

def area(self):
return self.length * self.width


class Square(Rectangle):
def __init__(self, length):
super().__init__(length, length)
#教え
Видео 8/22 1:45:00 -> end

ООП - Инкапсуляция
Объединение логики и данных для использования в одной упаковке.

Модификаторы доступа - в python это всеобщая договоренность, а не строгая механика
def public - доступно везде
def _protected - воступно везде но семантически указано что должно использоваться
внутри класса родителя и наследника
def private - поле не доступно извне родительского класса

при этом к private полю можно получить доступ если дописать название родительского класса с нижним
почеркиванием _ParentClass__private_field (опасная практика, по сути взлом)



class User:
def __init(self):
self.name = "User"

# зададим приватный метод
def __private_greet(self):
return f"Hello, {self.name}!"

# зададим публичный интерфейс для этого метода
def greet(self):
return self.__private_greet()

class John(User):
# попробуем переопределить приватный метод родителя
# на этот раз доберемся до оригинального метода обойдя name mangling
def _User__private_greet(self):
return f"Hello, John!"

# метод изменился
John().greet() # Hello, John!
Осуждаем?
#project #bot🔥 restaurant_delivery_bot intro

Реализовал бота для заказа доставки из ресторана

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

В админке позволяет получать уведомления о получении новых заказов, управлять ими(подтвердить, отменить). Пользователь получает уведомления о изменении статуса заказа.

Project Map
Стартовый экран

├── Наш ресторан

├── Меню
│ ├── Общая категория (еда, напитки)
│ │ ├── Категория
│ │ │ └── Товар
│ │
│ └── Корзина
│ ├── Подтверждение заказа
│ │ ├── Шаг 1
│ │ ├── Шаг 2
│ │ ├── Шаг 3
│ │ └── congratulation view

├── Мои заказы
│ └── Список заказов

└── Контакты
#hw lesson 6

Матрицы
Каждый раз возвращаясь хотел пропустить, зачем они мне нужны. Спойлер, в opencv (computer vision) каждая картинка представлена матрицей. Хочу знать о них все.

import random
from functools import reduce
from pprint import pprint


# Создать матрицу случайных чисел от a до b, размерность матрицы n*m
def generate_matrix(a, b, n, m):
return [
[random.randint(a, b) for _ in range(n)]
for _ in range(m)
]


# Найти максимальный элемент матрицы.

def get_matrix_max_value(matrix):
return max([max(row) for row in matrix])


# Найти минимальный элемент матрицы.

def get_matrix_min_value(matrix):
return min([min(row) for row in matrix])


# Найти сумму всех элементов матрицы.
def get_matrix_sum(matrix):
return sum(reduce(lambda s, x: s + x, matrix))


# Найти индекс ряда с максимальной суммой элементов.

def get_max_sum_row_index(matrix):
# джус от gpt (҂◡̀_◡́)ᕤ
return max(range(len(matrix)), key=lambda i: sum(matrix[i]))


# Найти индекс колонки с максимальной суммой элементов.
def get_max_sum_column_index(matrix):
# (҂◡̀_◡́)ᕤ
return max(range(len(matrix[0])), key=lambda i: sum([matrix[col_i][i] for col_i in range(len(matrix))]))


# Найти индекс ряда с минимальной суммой элементов
def get_min_sum_row_index(matrix):
return min(range(len(matrix)), key=lambda i: sum(matrix[i]))


# Найти индекс колонки с минимальной суммой элементов.
def get_min_sum_column_index(matrix):
return min(range(len(matrix[0])), key=lambda i: sum([matrix[col_i][i] for col_i in range(len(matrix))]))


# Обнулить все элементы выше главной диагонали.
def reset_above_main_diag(matrix):
for i in range(len(matrix)):
matrix[i] = matrix[i][:i + 1] + [0 for el_i in range(1, len(matrix[i])) if el_i > i]
return matrix


# Обнулить все элементы ниже главной диагонали.
def reset_below_main_diag(matrix):
for i in range(len(matrix)):
matrix[i] = [0 for _ in range(i)] + matrix[i][i:]
return matrix


# Создать матрицу равную сумме matrix_a и matrix_b.
def get_matrix_sum(matrix_a, matrix_b):
return [
[matrix_a[row_i][i] + matrix_b[row_i][i]
for i in range(len(matrix_a[row_i]))
] for row_i in range(len(matrix_a))
]

# Создать матрицу равную разности matrix_a и matrix_b.
def get_matrix_difference(matrix_a, matrix_b):
return [
[matrix_a[row_i][i] - matrix_b[row_i][i]
for i in range(len(matrix_a[row_i]))
] for row_i in range(len(matrix_a))
]


# Создать новую матрицу равную matrix_a умноженной на g. g вводится с
# клавиатура
def multyply_matrix_from_input():
n = 3
while (enter_num := int(input('enter num'))) != 'stop':
matrix = generate_matrix(1, 10, n, n)
print(matrix)
print([list(map(lambda x: x * enter_num, row)) for row in matrix])
#hw lesson 7

Укрепление работы с функциями.

# 1. inches to centimeters (дюймы - ширина большого пальца)
def convert_inches_to_centimeters(value: int):
return value * 2.54


# 2. Centimeters to inches
def convert_centimeters_to_inches(value: int):
if value == 0:
return value
return value / 2.54


# 3. Miles to kilometers (мили с древнего рима 1482 м)
def convert_miles_to_kilometers(value: int):
return value * 1.482


# 4. Kilometers to miles
def convert_kilometers_to_miles(value: int):
if value == 0:
return value
return value / 1.482


# 5. Pounds to Kilograms
def convert_pounds_to_kilograms(value: int):
return value * 16.3805


# 6. Kilograms to Pounds
def convert_kilograms_to_pounds(value: int):
if value == 0:
return value
return value / 16.3805


# 7. Ounces to grams
def convert_ounces_to_grams(value: int):
return value * 28.35


# 8. Grams to Ounces
def convert_grams_to_ounces(value: int):
if value == 0:
return value
return value / 28.35


# 9. Gallons to Liters
def convert_gallons_to_liters(value: int):
return value * 4.5


# 10. Liters to Gallons
def convert_liters_to_gallons(value: int):
if value == 0:
return value
return value / 4.5


# 11. Pints to Liters
def convert_pints_to_liters(value: int):
return value * 0.473


# 12. Liters to pints
def convert_liters_to_pints(value: int):
if value == 0:
return value
return value / 0.473


Тесты


from homework.tasks_7 import (
convert_inches_to_centimeters,
convert_centimeters_to_inches,
convert_miles_to_kilometers,
convert_kilometers_to_miles,
convert_pounds_to_kilograms,
convert_kilograms_to_pounds,
convert_ounces_to_grams,
convert_grams_to_ounces,
convert_gallons_to_liters,
convert_liters_to_gallons,
convert_pints_to_liters,
convert_liters_to_pints
)
import pytest
from decimal import Decimal


# Тесты с использованием @pytest.mark.parametrize
@pytest.mark.parametrize(
"enter_value, expected_value",
[
(1, 2.54),
(0, 0),
(-1, -2.54)
]
)
def test_convert_inches_to_centimeters(enter_value, expected_value):
assert convert_inches_to_centimeters(enter_value) == pytest.approx(expected_value)


@pytest.mark.parametrize(
"enter_value, expected_value",
[
(2.54, 1),
(0, 0),
(-2.54, -1)
]
)
def test_convert_centimeters_to_inches(enter_value, expected_value):
assert convert_centimeters_to_inches(enter_value) == pytest.approx(expected_value)


@pytest.mark.parametrize(
"enter_value, expected_value",
[
(1, 1.60934),
(0, 0),
(-1, -1.60934)
]
)
def test_convert_miles_to_kilometers(enter_value, expected_value):
assert convert_miles_to_kilometers(enter_value) == pytest.approx(expected_value)


@pytest.mark.parametrize(
"enter_value, expected_value",
[
(1.60934, 1),
(0, 0),
(-1.60934, -1)
]
)
def test_convert_kilometers_to_miles(enter_value, expected_value):
assert convert_kilometers_to_miles(enter_value) == pytest.approx(expected_value)


@pytest.mark.parametrize(
"enter_value, expected_value",
[
(1, 0.453592),
(0, 0),
(-1, -0.453592)
]
)
def test_convert_pounds_to_kilograms(enter_value, expected_value):
assert convert_pounds_to_kilograms(enter_value) == pytest.approx(expected_value)


@pytest.mark.parametrize(
"enter_value, expected_value",
[
(0.453592, 1),
(0, 0),
(-0.453592, -1)
]
)
def test_convert_kilograms_to_pounds(enter_value, expected_value):
assert convert_kilograms_to_pounds(enter_value) == pytest.approx(expected_value)
#hw lesson 8
Math
# Описать функцию fact2( n ), вычисляющую двойной факториал :n!! =
# 1·3·5·...·n, если n — нечетное; n!! = 2·4·6·...·n, если n — четное (n > 0 —
# параметр целого типа. С помощью этой функции найти двойные
# факториалы пяти данных целых чисел [01-11.2-Proc35]
def fact2(n):
if n < 3:
return n
return reduce(lambda x, a: a * x, [num for num in range(2 - (n & 1), n + 1, 2)])


# Даны три слова. Выяснить, является ли хоть одно из них палиндромом
# ("перевертышем"), т. е. таким, которое читается одинаково слева направо и
# справа налево. (Определить функцию, позволяющую распознавать слова
# палиндромы.)[03-10.32] (просто реализовал функцию палиндром)
def is_palindrome(word: str) -> bool:
if len(word) < 1:
return False
if word == word[::-1]:
return True
return False


# Описать функцию Sin1( x , ε ) вещественного типа (параметры x , ε —
# вещественные, ε > 0), находящую приближенное значение функции sin( x ):
# sin( x ) = x – x ^3 /(3!) + x^ 5 /(5!) – ... + (–1) ^ n · x^( 2·n+1) /((2· n +1)!) + ... .
# В сумме учитывать все слагаемые, модуль которых больше ε . С помощью
# Sin1 найти приближенное значение синуса для данного x при шести данных
# ε . [01-11.3-Proc41]

def sin1(x, epsilon):
s = x
n = 1
fact_collector = 1
while True:
fact_collector = fact_collector * (2 * n) * (2 * n + 1)
# сначала написал -1 ** 2, но в python - перед единицей это унарный оператор
# и соответственно степень имеет высший приоритет -_-
symb = (-1) ** n
num_path = (x ** (2 * n + 1))
temp_s = symb * num_path / fact_collector
if abs(temp_s) < epsilon:
break
s += temp_s
n += 1

return s


Тесты


@pytest.mark.parametrize(
"enter_value, expected_value",
[
(1, 1),
(0, 0),
(9, 945),
(6, 48),
]
)
def test_fact2(enter_value, expected_value):
assert fact2(enter_value) == pytest.approx(expected_value)


# Здесь предполагается, что функция Sin1 уже определена

@pytest.mark.parametrize(
"enter_value, expected_value",
[
('sor', False),
('', False),
('sos', True),
('poop', True),
]
)
def test_is_palindrome(enter_value, expected_value):
assert is_palindrome(enter_value) == pytest.approx(expected_value)


@pytest.mark.parametrize(
"x, epsilon, expected_approx",
[
(0, 0.1, 0), # sin(0) = 0
(math.pi / 6, 0.01, 0.5), # sin(π/6) ≈ 0.5
(math.pi / 4, 0.01, math.sqrt(2) / 2), # sin(π/4) ≈ √2/2
(math.pi / 2, 0.01, 1), # sin(π/2) = 1
(math.pi, 0.01, 0), # sin(π) = 0
(3 * math.pi / 2, 0.01, -1), # sin(3π/2) = -1
(2 * math.pi, 0.01, 0), # sin(2π) = 0
# Добавьте дополнительные тестовые случаи по вашему выбору
]
)
def test_sin1(x, epsilon, expected_approx):
assert sin1(x, epsilon) == pytest.approx(expected_approx, rel=epsilon)