Приветствую подписчиков.
Я даже несколько удивлён как это вы еще не разбежались 😻))
Многие мне пишут в личку с вопросом "Где брать курсы если сайт закрылся?".
Отвечаю — сайт не закрылся❗️
Ввиду некоторой обстановки 💣⚔️🚓 💥 мой хостинг (Украинский кстати) немножко "закончился".
Мой хороший знакомый, админ данного хостинга, включил мой сервер на пару часов и я скачал все данные. После чего создал новый сервер в Европе и поднял там сайт.
На данный момент я закончил настройку и теперь сайт снова доступен.
А так же добавил домен COM, для тех у кого RU блокируют.
Теперь сайт доступен по адресам:
https://cgninjas.ru/
https://cgninjas.com/
(возможно на com почта не будет работать)
Также просят выложить всё на Youtube или на Torrent. Да я не против, только исходники у меня пропали вместе с HDD, так что надо потратить немало времени чтобы скачать, систематизировать и залить. Если вдруг выкрою недельку на это, то обязательно сделаю)))
▫️Погодите, а что с каналом? он тоже всё?
Нет, ввиду всё тех же событий 💥 потух творческий запал, и мотивация пропала...
Но идеи есть, заготовки тем тоже. Возможно, я жду хороших новостей.
Обязательно продолжу серию заметок... надеюсь скоро. А до тех пор я не хочу вас раздражать глупой рекламой глупых каналов (которые запрудили телеграм и предложения которой приходят регулярно) а лучше просто помолчу.
"Благодарим за понимание ©"
ЗЫ. Не пишите пжлст в личку, есть чат для этого
➡️ CGNinjasChat
#offtop
Я даже несколько удивлён как это вы еще не разбежались 😻))
Многие мне пишут в личку с вопросом "Где брать курсы если сайт закрылся?".
Отвечаю — сайт не закрылся❗️
Ввиду некоторой обстановки 💣⚔️🚓 💥 мой хостинг (Украинский кстати) немножко "закончился".
Мой хороший знакомый, админ данного хостинга, включил мой сервер на пару часов и я скачал все данные. После чего создал новый сервер в Европе и поднял там сайт.
На данный момент я закончил настройку и теперь сайт снова доступен.
А так же добавил домен COM, для тех у кого RU блокируют.
Теперь сайт доступен по адресам:
https://cgninjas.ru/
https://cgninjas.com/
(возможно на com почта не будет работать)
Также просят выложить всё на Youtube или на Torrent. Да я не против, только исходники у меня пропали вместе с HDD, так что надо потратить немало времени чтобы скачать, систематизировать и залить. Если вдруг выкрою недельку на это, то обязательно сделаю)))
▫️Погодите, а что с каналом? он тоже всё?
Нет, ввиду всё тех же событий 💥 потух творческий запал, и мотивация пропала...
Но идеи есть, заготовки тем тоже. Возможно, я жду хороших новостей.
Обязательно продолжу серию заметок... надеюсь скоро. А до тех пор я не хочу вас раздражать глупой рекламой глупых каналов (которые запрудили телеграм и предложения которой приходят регулярно) а лучше просто помолчу.
"Благодарим за понимание ©"
ЗЫ. Не пишите пжлст в личку, есть чат для этого
➡️ CGNinjasChat
#offtop
👍47❤29
Я нашел самый быстрый способ поднять свой независимый и бесплатный VPN
Сразу оговорка, платить придётся только за хостинг.
1️⃣ Покупаем сервер где-то на просторах интернета. Конечно же сервер должен находиться за пределами страны. Например я закупился на https://eurohoster.org/ (не реклама). Проверяйте лимиты по трафику, в идеале - без ограничений.
2️⃣ Ставим docker
Самый простой способ поднять сервис WireGuard c WebUI это проект wg-easy
Код и документация здесь
https://github.com/weejewel/wg-easy
Запускаем контейнер:
https://github.com/weejewel/wg-easy#2-run-wireguard-easy
Для тех кто с DockerCompose, забираем файл здесь:
https://gist.github.com/paulwinex/be87f79687b96786098ec8fa6a8e251c
В обоих случаях потребуется поменять две переменные:
Остальные параметры указаны ниже на странице github https://github.com/weejewel/wg-easy#options
4️⃣ Ставим клиента
Все доступные клиенты здесь
https://www.wireguard.com/install/
Есть возможность добавить клиента в Network Manager для управления подключением через UI. Установка зависит от вашей системы, ищите мануалы в сети, их много.
https://github.com/max-moser/network-manager-wireguard
Скрипт установки для RasperryPi
https://gist.github.com/paulwinex/c2c4090f19dbe8bd1253c5744f3f06e1
ЗЫ. Конечно же это не "самый простой" и далеко не единственный способ. А просто тот, который использую я сам.
#offtop #linux
Сразу оговорка, платить придётся только за хостинг.
1️⃣ Покупаем сервер где-то на просторах интернета. Конечно же сервер должен находиться за пределами страны. Например я закупился на https://eurohoster.org/ (не реклама). Проверяйте лимиты по трафику, в идеале - без ограничений.
2️⃣ Ставим docker
sudo apt install docker.ioЕсли удобней с DockerCompose то ставим и его
sudo apt install docker-compose3️⃣ Ставим WG-EASY
Самый простой способ поднять сервис WireGuard c WebUI это проект wg-easy
Код и документация здесь
https://github.com/weejewel/wg-easy
Запускаем контейнер:
https://github.com/weejewel/wg-easy#2-run-wireguard-easy
Для тех кто с DockerCompose, забираем файл здесь:
https://gist.github.com/paulwinex/be87f79687b96786098ec8fa6a8e251c
В обоих случаях потребуется поменять две переменные:
WG_HOST - внешний статичный IP вашего сервераPASSWORD - придумайте пароль для WEB UIОстальные параметры указаны ниже на странице github https://github.com/weejewel/wg-easy#options
4️⃣ Ставим клиента
Все доступные клиенты здесь
https://www.wireguard.com/install/
Есть возможность добавить клиента в Network Manager для управления подключением через UI. Установка зависит от вашей системы, ищите мануалы в сети, их много.
https://github.com/max-moser/network-manager-wireguard
Скрипт установки для RasperryPi
https://gist.github.com/paulwinex/c2c4090f19dbe8bd1253c5744f3f06e1
ЗЫ. Конечно же это не "самый простой" и далеко не единственный способ. А просто тот, который использую я сам.
#offtop #linux
GitHub
GitHub - WeeJeWel/wg-easy: The easiest way to run WireGuard VPN + Web-based Admin UI.
The easiest way to run WireGuard VPN + Web-based Admin UI. - WeeJeWel/wg-easy
👍18🔥2
Релиз Python 3.11 В прямом эфире
▶️ https://www.youtube.com/watch?v=PGZPSWZSkJI
▶️ Подробности по релизу
https://docs.python.org/3.11/whatsnew/3.11.html
▶️ https://www.youtube.com/watch?v=PGZPSWZSkJI
▶️ Подробности по релизу
https://docs.python.org/3.11/whatsnew/3.11.html
YouTube
Python 3.11 Release
Timestamps
00:00 - Introduction
24:30 - Brandt Bucher, Specializing Adaptive Interpreter
50:40 - Mark Shannon, Other Speedups
1:07:42 - Irit Katriel, Exception Improvements and Features
1:42:13 - Pablo Galindo, Better Tracebacks
1:58:46 - Pablo Galindo, tomllib…
00:00 - Introduction
24:30 - Brandt Bucher, Specializing Adaptive Interpreter
50:40 - Mark Shannon, Other Speedups
1:07:42 - Irit Katriel, Exception Improvements and Features
1:42:13 - Pablo Galindo, Better Tracebacks
1:58:46 - Pablo Galindo, tomllib…
👍10😱2
Как не передавать аргумент в функцию если она его не ждёт?
Как-то раз я делал модуль с функциями, которые вызывались как фоновые задачи. В основном они принимали чёткий список позиционных аргументов. И вот, в разгар разработки, пришла новая фича - в каждую такую функцию теперь передаётся Lock-объект. Он позволяет сделать выполнение этой функции синхронным на разных воркерах (как и положено любому локеру).
Но вот проблема, в новых функциях, где нужен локер, я его, конечно же, принимаю как аргумент. Но в старых функциях он не предусмотрен. Часто функции вообще без аргументов.
Какие варианты решения?
▫️ Добавить во всех функциях в аргументы
▫️Проверить, может ли функция принять аргумент с определённым именем. И если не может то не передавать. Это можно сделать с помощью стандартной функции
#tricks
Как-то раз я делал модуль с функциями, которые вызывались как фоновые задачи. В основном они принимали чёткий список позиционных аргументов. И вот, в разгар разработки, пришла новая фича - в каждую такую функцию теперь передаётся Lock-объект. Он позволяет сделать выполнение этой функции синхронным на разных воркерах (как и положено любому локеру).
Но вот проблема, в новых функциях, где нужен локер, я его, конечно же, принимаю как аргумент. Но в старых функциях он не предусмотрен. Часто функции вообще без аргументов.
Какие варианты решения?
▫️ Добавить во всех функциях в аргументы
**kwargs. Это решит все проблемы. Строго говоря, это надо было сделать сразу. Теперь таски не будут падать из-за неизвестного аргумента. И теперь следует не забывать добавлять **kwargs в новых функциях. Но что, если нет возможности изменять код? Тогда...▫️Проверить, может ли функция принять аргумент с определённым именем. И если не может то не передавать. Это можно сделать с помощью стандартной функции
inspect.signature
from inspect import signatureТеперь можно проверить, ожидает ли функция параметр с определённым именем
def func(x, y, z=True):
pass
sig = signature(func)
print(sig)
# <Signature (x, y, z=True)>
print(sig.parameters)
mappingproxy(OrderedDict([('x', <Parameter "x">), ('y', <Parameter "y">), ('z', <Parameter "z=True">)]))
print('lock' in sig.parameters)
# False
Финальный псевдокодfrom tasks import my_task, LockClassКонечно же, наличие этого имени не гарантирует что функция ожидает именно этот тип. Но это уже нюансы реализации 😼
from inspect import signature
task_kwargs = {}
lock = LockClass()
if 'lock' in signature(my_task).parameters:
task_kwargs['lock'] = lock
my_task(**task_kwargs)
#tricks
👍17🤔2🔥1
Сделал простой скрипт для управления температурой кулера Raspberry Pi.
- Зачем? Их же полно готовых! Даже дефолтные инструменты есть.
Хотелось сделать этот велосипед по-своему 😁
▫️Пороговых температур две: Одна контролирует момент включения, другая выключения. Например, выше 80 - включаем. Остыл до 50 - выключаем.
▫️ Значения пороговых температур заипсывается в специальном файле и считывается каждый раз при проверке темературы без рестарта сервиса.
Исходники и схема.
https://github.com/paulwinex/rpi_fan_control
ЗЫ. В схеме присуствует сопротивление. Это требуется только если нужно уменьшить скорость вращения кулера. Мой на полных оборотах сильно гудит, пришлось поставить.
#sources #rpi
- Зачем? Их же полно готовых! Даже дефолтные инструменты есть.
Хотелось сделать этот велосипед по-своему 😁
▫️Пороговых температур две: Одна контролирует момент включения, другая выключения. Например, выше 80 - включаем. Остыл до 50 - выключаем.
▫️ Значения пороговых температур заипсывается в специальном файле и считывается каждый раз при проверке темературы без рестарта сервиса.
Исходники и схема.
https://github.com/paulwinex/rpi_fan_control
ЗЫ. В схеме присуствует сопротивление. Это требуется только если нужно уменьшить скорость вращения кулера. Мой на полных оборотах сильно гудит, пришлось поставить.
#sources #rpi
👍10❤3
Помните трик с заменой строки в консоли с помощью символа
Что будет если сделать несоклько таких символов? Мы вернёмся на несколько строк выше? Нет, так не сработает.
Как же сделать замену нескольких строк?
Для этого нужна хитрая комбинация символов:
Итого, наша абракадабра значит - подняться на строку вверх и удалть всю строку.
Полный список специальных символов можно найти на этой странице.
Эти функции консоли широко используются. Например модуль colorama использует модификации для изменения цвета текста в консоли.
В демке на видео показана манипуляция тремя строками в консоли. Пишем три строки, удаляем три строки, и тд.
➡️ Код с демонстрацией
#triks
"\r"? Рассказывал в этом посте.Что будет если сделать несоклько таких символов? Мы вернёмся на несколько строк выше? Нет, так не сработает.
Как же сделать замену нескольких строк?
Для этого нужна хитрая комбинация символов:
\x1b[1A\x1b[2K
Что это вообще за магия? Это специальный код для управления курсором консоли.\x1b : экранирующий символ означающий что дальше следует специальный символ. Он же символ ESC[1A : команда "поднять курсор вверх". Есть и другие команды для перемещения курсора в разные стороны.[2K : удалить текущую строку. "2" означает всю строку. Еще есть опции: "0" - от курсора до конца, "1" - от курсора к началу.Итого, наша абракадабра значит - подняться на строку вверх и удалть всю строку.
Полный список специальных символов можно найти на этой странице.
Эти функции консоли широко используются. Например модуль colorama использует модификации для изменения цвета текста в консоли.
В демке на видео показана манипуляция тремя строками в консоли. Пишем три строки, удаляем три строки, и тд.
➡️ Код с демонстрацией
#triks
🔥12
Вышла альфа версия Python 3.12. Можно оценить что нам готовят.
Полезно глянуть что будет удалено в 3.13.
Еще можно посмотреть стрим на час про новинки.
#release
Полезно глянуть что будет удалено в 3.13.
distutils уже удалили.Еще можно посмотреть стрим на час про новинки.
#release
Python documentation
What’s New In Python 3.12
Editor, Adam Turner,. This article explains the new features in Python 3.12, compared to 3.11. Python 3.12 was released on October 2, 2023. For full details, see the changelog. Summary – Release hi...
🔥6😁1
Как получить путь к файлу текущего класса если метод получения пути находится в родительском классе в другом файле?
Например, представим такую ситуацию:
Чтобы получить правильный путь нам следует:
▫️ получить имя модуля текущего класса
Например, представим такую ситуацию:
# module1.py ###Что покажет код:
class BaseCls:
@classmethod
def get_path(cls):
print(__file__)
# module2.py ###
from module1 import BaseCls
class MainCls(BaseCls):
pass
import module2Мы ожидаем что путь будет к файлу
module2.MainCls.get_path()
module2.py, но переменная __file__ объявлена внутри файла module1.py и поэтому будет указывать именно на него.Чтобы получить правильный путь нам следует:
▫️ получить имя модуля текущего класса
module_name = module2.MainCls.__module__▫️ найти этот модуль в списке импортированных модулей
mod = sys.modules[module_name]▫️ получить значение переменной
__file__
filepath = mod.
__file__
Вся эта процедура, причём для любого типа объекта, есть в функции inspect.getfile(). Так что наш метод должен выглядеть так:# module1.pyТеперь из вызов этого метода из класса
import inspect
class BaseCls:
@classmethod
def get_path(cls):
print(inspect.getfile(cls))
MainCls найдёт путь к файлу module2.py
#tricks👍6
В Linux стандартными средствами можно использовать часть оперативной памяти как диск. Для этого требуется указать тип монтирования
▫️ Скорость работы с таким каталогом выше чем многие SSD и тем более HDD.
▫️ Если у вас очень быстрый SSD на NVMe M.2 то такой способ особо не прибавит вам скорости, но поможет сохранить ресурс SSD когда требуется обрабатывать очень много мелких файлов и оперативка позволяет выделить нужный объем.
▫️ Оперативка это энергозависимая память, поэтому выключении питания все файлы безвозвратно теряются. Такой "non persistent" каталог гарантирует удаление временных файлов.
Я написал небольшой скрипт для условного теста и сравнения скорости копирования файлов между SSD и RAM.
Вот мои результаты:
На моём железе прирост скорости ~2x. Плюс экономия ресурса SSD.
В Windows такой фишки по умолчанию нет, но обязательно найдутся аналогичные решения
#linux #triks
tmpfs в команде mountmount -t tmpfs -o size=5G tmpfs /mnt/ramТеперь путь
/mnt/ram можно использовать как обычный каталог. Для чего это может быть нужно?▫️ Скорость работы с таким каталогом выше чем многие SSD и тем более HDD.
▫️ Если у вас очень быстрый SSD на NVMe M.2 то такой способ особо не прибавит вам скорости, но поможет сохранить ресурс SSD когда требуется обрабатывать очень много мелких файлов и оперативка позволяет выделить нужный объем.
▫️ Оперативка это энергозависимая память, поэтому выключении питания все файлы безвозвратно теряются. Такой "non persistent" каталог гарантирует удаление временных файлов.
Я написал небольшой скрипт для условного теста и сравнения скорости копирования файлов между SSD и RAM.
Вот мои результаты:
Single File Size: 30.0GbСкрипт для теста ↗️
ssd > ssd: 0:00:12.850 / 2.3Gb/s
sdd > ram: 0:00:06.453 / 4.6Gb/s
ram > ram: 0:00:06.995 / 4.3Gb/s
ram > sdd: 0:00:06.217 / 4.8Gb/s
Dir size: 32.7Gb, File count: 11127
ssd > ssd: 0:00:15.063 / 2.2Gb/s
sdd > ram: 0:00:08.486 / 3.9Gb/s
ram > ram: 0:00:08.032 / 4.1Gb/s
ram > sdd: 0:00:07.026 / 4.7Gb/s
На моём железе прирост скорости ~2x. Плюс экономия ресурса SSD.
В Windows такой фишки по умолчанию нет, но обязательно найдутся аналогичные решения
#linux #triks
Gist
Test copy speed with ramdisk on linux
Test copy speed with ramdisk on linux. GitHub Gist: instantly share code, notes, and snippets.
👍9🔥2❤1
Популярность имеет свои минусы. Чем популярней язык программирования, тем выше его распространённость, а значит найдутся те кто поспешит воспользоваться этим.
С ростом популярности Python всё больше на PyPi появляется вредоносных пакетов. Трояны, стиллеры и доставщики более опасных вредоносов.
Команда PyPi постоянно мониторит подобные случаи но и их возможности достигли предела. В результате сервис временно закрывает возможность заливки новых пакетов и регистрации юзеров.
PyPI new user and new project registrations temporarily suspended
Возможно одной из причин большого наплыва вредоносов является резко возросшая доступность их создания. Сегодня любой, даже не программист, может попросить у ChatGPT написать необходимый код и все инструкции для атаки.
Основной тип атаки - рассчёт на опечатку в названии пакета. Если невнимательный программист случайно установит
Чтобы избежать подобных факапов я рекомендую:
▫️ Всегда работайте в виртуальном окружении, неизвестные проекты устанавливайте внутри контейнеров.
▫️ Используйте файл
▫️ Очень внимательно пишите названия пакетов, а после написания проверьте еще раз. Сверьте с названием из документации.
▫️ После успешных тестов всегда фиксируйте версию пакета. Бывали случаи когда опасный код добавляли в новые версии. К тому же и без этой опасности не рекомендуется ставить по умолчанию последнюю версию.
▫️ Используйте вспомогательные инструменты для проверки безопасности, например https://pyup.io/safety или https://github.com/PyCQA/bandit. Они помогут не только найти опасный код в чужих пакетах, но и ваш код проверит на уязвимости.
Будем надеяться что PyPi переосмыслит методы борьбы с вредоносами, например внедрит ИИ для проверки как симметричный шаг.
#offtop
С ростом популярности Python всё больше на PyPi появляется вредоносных пакетов. Трояны, стиллеры и доставщики более опасных вредоносов.
Команда PyPi постоянно мониторит подобные случаи но и их возможности достигли предела. В результате сервис временно закрывает возможность заливки новых пакетов и регистрации юзеров.
PyPI new user and new project registrations temporarily suspended
Возможно одной из причин большого наплыва вредоносов является резко возросшая доступность их создания. Сегодня любой, даже не программист, может попросить у ChatGPT написать необходимый код и все инструкции для атаки.
Основной тип атаки - рассчёт на опечатку в названии пакета. Если невнимательный программист случайно установит
pilow или djangoo, считай что вредонос уже в системе.Чтобы избежать подобных факапов я рекомендую:
▫️ Всегда работайте в виртуальном окружении, неизвестные проекты устанавливайте внутри контейнеров.
▫️ Используйте файл
requirements.txt вместо ручной установки пакетов▫️ Очень внимательно пишите названия пакетов, а после написания проверьте еще раз. Сверьте с названием из документации.
▫️ После успешных тестов всегда фиксируйте версию пакета. Бывали случаи когда опасный код добавляли в новые версии. К тому же и без этой опасности не рекомендуется ставить по умолчанию последнюю версию.
▫️ Используйте вспомогательные инструменты для проверки безопасности, например https://pyup.io/safety или https://github.com/PyCQA/bandit. Они помогут не только найти опасный код в чужих пакетах, но и ваш код проверит на уязвимости.
Будем надеяться что PyPi переосмыслит методы борьбы с вредоносами, например внедрит ИИ для проверки как симметричный шаг.
#offtop
status.python.org
PyPI new user and new project registrations temporarily suspended.
Python Infrastructure's Status Page - PyPI new user and new project registrations temporarily suspended..
👍20❤2👎1🤔1
У тех, кто часто работает в терминале, есть привычка вызова особо часто используемых команд. например
Вместо команды
И так уж вышло, что эта привычка невольно у меня включается и при работе в REPL. Для быстрого выхода я жму
В общем, настолько высосанную из пальца проблему надо еще поискать 😆, но я нашел для неё решение!
Как это работает?
▫️ динамически создаётся новый тип объекта с помощью конструкции
▫️ в этом методе вызывается команда
▫️ имя
▫️ Нужно как-то добавлять это в стартап. Тут нам поможет startup script
Аналогичным способом можно сделать и другие действия, но стоит помнить что это нестандартное поведение в Python, в прод не оставляйте!
Пару раз я вставлял аналогичные объекты в интерактивную консоль для дебага, они там выполняли роль шорткатов для каких-то наборов действий
PS. Не очень-то это похоже на трик или лайфхак. Это скорей демонстрация гибкости языка в решениинадуманных нестандартных проблем.
#tricks
cd, ls, mc...Вместо команды
exit можно использовать Ctrl+D, и это удобно. И так уж вышло, что эта привычка невольно у меня включается и при работе в REPL. Для быстрого выхода я жму
Ctrl+D, и это работает, но только в Linux. В Windows это совсем не работает, так как там надо нажимать Ctrl+Z. И был бы Windows не такой mustdie если бы этого хватило, но требуется еще нажать Enter (если знаете быстрый выход из REPL на винде, то подсказывайте, я не WinUser). Иногда мне быстрей и привычней вбить exit и нажать Enter, как в bash, но и тут подстава - еще нужны скобки вызова🤬.В общем, настолько высосанную из пальца проблему надо еще поискать 😆, но я нашел для неё решение!
q = type('q', (object,), {'__repr__': lambda *args: exit()})()
Этот код вставляется в стартап скрипт REPL и создаёт новый объект q. Теперь для выхода из REPL достаточно написать символ q и нажать Enter. Работает одинаково на Linux и Windows.Как это работает?
▫️ динамически создаётся новый тип объекта с помощью конструкции
type(NAME, (BASETYPES,), {ATTRS,})
▫️ в атрибутах создаётся оверрайд метода __repr__, который отвечает за распечатку объекта в REPL▫️ в этом методе вызывается команда
exit()
То есть команда выхода срабатывает как только вы пытаетесь распечатать этот объект в консоли. Именно отображение его репрезентации как объекта а не через не print(), который использует метод __str__.
Аналогично работающий код выглядит так:class Q:
def __repr__(self):
exit()
q = Q()
Из минусов можно выделить следующее:▫️ имя
q занято, но никто не мешает сделать что-то более уникальное▫️ Нужно как-то добавлять это в стартап. Тут нам поможет startup script
Аналогичным способом можно сделать и другие действия, но стоит помнить что это нестандартное поведение в Python, в прод не оставляйте!
Пару раз я вставлял аналогичные объекты в интерактивную консоль для дебага, они там выполняли роль шорткатов для каких-то наборов действий
PS. Не очень-то это похоже на трик или лайфхак. Это скорей демонстрация гибкости языка в решении
#tricks
Telegram
Python Заметки
Startup скрипт для REPL.
Как выполнить скрипт сразу после старта интерактивной консоли Python?
Для начала понять бы зачем это может понадобиться. А причины бывают достаточно весомые
- автоматизировать одни и те же действия которые вы повторяете при старте…
Как выполнить скрипт сразу после старта интерактивной консоли Python?
Для начала понять бы зачем это может понадобиться. А причины бывают достаточно весомые
- автоматизировать одни и те же действия которые вы повторяете при старте…
😁7👍3👎1
Debian 12 не позволяет глобально устанавливать Python пакеты через
Такое поведение описано в PEP 668.
Это сделано для минимизации конфликтов версий системных пакетов.
Если вам действительно нужно поставить что-то глобально, используйте
#pep
pip. Не поможет даже sudo.Такое поведение описано в PEP 668.
Это сделано для минимизации конфликтов версий системных пакетов.
Если вам действительно нужно поставить что-то глобально, используйте
apt install python-packagenameВ остальных случаях всегда используйте виртуальное окружение.
#pep
Python Enhancement Proposals (PEPs)
PEP 668 – Marking Python base environments as “externally managed” | peps.python.org
A long-standing practical problem for Python users has been conflicts between OS package managers and Python-specific package management tools like pip. These conflicts include both Python-level API incompatibilities and conflicts over file ownership.
👍18
SQLAlchemy - это один из самых популярных ORM для работы с базами данных из Python.
- поддерживат все популярные базы данных
- не привязана к какому-либо фреймворку (как, например, Django ORM)
- поддерживает асинхрон
- позволяет удобно (питонично) делать довольно сложные SQL запросы
15 июля вышла первая версия из ветки 2.0 и это хорошйи повод изучить эту библиотеку если еще не начали.
Подобрал вам ресурсы для изучения:
- Вебинар и урок про новую SQLAlchemy2.0 от Mike Bayer (автор sqlalchemy и alembic ) с онлайн конференции pythonwebconf:
https://www.youtube.com/watch?v=Uym2DHnUEno
- Для тех кто на английском не очень, есть онлайн книга на руссом от https://t.iss.one/massonnn_yt.
А так же видео версия:
https://www.youtube.com/watch?v=leeC0fpAY-E&list=PLN0sMOjX-lm5Pz5EeX1rb3yilzMNT6qLM
Лично я использую алхимию в связке с FastAPI и пока всё устраивает
#tricks #libs
- поддерживат все популярные базы данных
- не привязана к какому-либо фреймворку (как, например, Django ORM)
- поддерживает асинхрон
- позволяет удобно (питонично) делать довольно сложные SQL запросы
15 июля вышла первая версия из ветки 2.0 и это хорошйи повод изучить эту библиотеку если еще не начали.
Подобрал вам ресурсы для изучения:
- Вебинар и урок про новую SQLAlchemy2.0 от Mike Bayer (автор sqlalchemy и alembic ) с онлайн конференции pythonwebconf:
https://www.youtube.com/watch?v=Uym2DHnUEno
- Для тех кто на английском не очень, есть онлайн книга на руссом от https://t.iss.one/massonnn_yt.
А так же видео версия:
https://www.youtube.com/watch?v=leeC0fpAY-E&list=PLN0sMOjX-lm5Pz5EeX1rb3yilzMNT6qLM
Лично я использую алхимию в связке с FastAPI и пока всё устраивает
#tricks #libs
www.sqlalchemy.org
The Database Toolkit for Python
👍22
Как в Linux отправить картинку на печать из Python? Это можно сделать с помощью CUPS - Common Unix Printing System
▫️ Ставим зависимости
▫️ Ставим зависимости
sudo apt install -y libcups2-dev python3-dev gcc▫️ Устанавливаекм библиотеку-обертку
pip install pycups▫️ Печатаем
import cups#libs
# устанавливаем коннект
conn = cups.Connection()
# получаем список принтеров
printers = conn.getPrinters()
print(printers)
printer_name = list(printers.keys())[0]
# отправляем на печать
conn.printFile(printer_name, image_path, "Image Print", {})
GitHub
GitHub - OpenPrinting/pycups: python-cups upstream repo
python-cups upstream repo. Contribute to OpenPrinting/pycups development by creating an account on GitHub.
👍8
This media is not supported in your browser
VIEW IN TELEGRAM
Прошлый пост про печать появился неспроста!
Недавно мне потребовалось напечатать большую версию чертежа. Нужен был инстурмент, аналогичный многостраничной печати в CorelDraw но под Linux.
Поэтому я решил ... чтобывыдумали???... да, сделать свой велосипед 😂
И вот что у меня вышло.
➡️ Tile Printer
▫️Интерактивное позиционирование картинки
▫️Отправка на печать или сохранение в файлы
▫️Настройка отступов
▫️Можно указать DPI
ЗЫ. Не судите строго, сделано всё за 1 день.
ЗЗЫ. Да, я гуглил аналоги. Самый советуемый инструмент posterazor не подошел по функционалу. Остальные не стоят внимания.
#source
Недавно мне потребовалось напечатать большую версию чертежа. Нужен был инстурмент, аналогичный многостраничной печати в CorelDraw но под Linux.
Поэтому я решил ... чтобывыдумали???... да, сделать свой велосипед 😂
И вот что у меня вышло.
➡️ Tile Printer
▫️Интерактивное позиционирование картинки
▫️Отправка на печать или сохранение в файлы
▫️Настройка отступов
▫️Можно указать DPI
ЗЫ. Не судите строго, сделано всё за 1 день.
ЗЗЫ. Да, я гуглил аналоги. Самый советуемый инструмент posterazor не подошел по функционалу. Остальные не стоят внимания.
#source
❤8🤩3
Как проверить является ли директория пустой?
Самый простой способ:
Во втором случае мы получаем генератор, который под капотом использует тот же
Теперь представим что в директории 10к файлов
Для того чтобы ускорить проверку лучше воспользоваться функцией os.scandir(). Она работает на много быстрей и возвращает итератор с объектами os.DirEntry.
Чтобы узнать есть ли в директории хоть один файл достаточно использовать функцию
Самый простой способ:
if os.listdir(path):Тоже самое с
...
pathlib
p = Path(path)В первом случае функция
if list(p.iterdir()):
...
os.listdir возвращает полный список файлов. Нам остаётся проверить есть ли там что-либо.Во втором случае мы получаем генератор, который под капотом использует тот же
listdir.Теперь представим что в директории 10к файлов
for i in range(10000):Не сказать, что при наличии SSD это проблема, но когда таких операций много, мы начинаем терять время, особенно с
Path(f'/tmp/test/test{i}.txt').touch()
pathlib.import timeitТо есть мы получаем список всех 10к файлов просто чтобы узнать что там есть файлы. Хотя нам надо узнать есть ли по указанному пути хотя бы один файл.
test_path = '/tmp/test'
count = 1000
>>> timeit.timeit('list(os.listdir(p))', setup=f'import os;p="{test_path}"', number=count)
2.281363710993901
>>> timeit.timeit('list(p.iterdir())', setup=f'from pathlib import Path;p=Path("{test_path}")', number=count)
5.6957218300012755
Для того чтобы ускорить проверку лучше воспользоваться функцией os.scandir(). Она работает на много быстрей и возвращает итератор с объектами os.DirEntry.
Чтобы узнать есть ли в директории хоть один файл достаточно использовать функцию
next()
next(os.scandir(path))Но если директория пустая, то мы получим ошибку. Поэтому добавляем значение по умолчанию и можно использовать конструкцию в условном операторе
if next(os.scandir(path), None):Либо используем функцию
...
any(), так как она завершится сразу после нахождения первого файла или если итератор пуст.if any(os.scandir(path)):Сравним скорость
...
>>> timeit.timeit('next(os.scandir(p), None)', setup=f'import os;p="{test_path}"', number=count)
0.2183076049986994
>>> timeit.timeit('any(os.scandir(p))', setup=f'import os;p="{test_path}"', number=count)
0.21016486900043674
#tricksPython documentation
os — Miscellaneous operating system interfaces
Source code: Lib/os.py This module provides a portable way of using operating system dependent functionality. If you just want to read or write a file see open(), if you want to manipulate paths, s...
👍16❤4
⭐️ Встречаем релиз 3.12
Из того что мне приглянулось:
▫️ Всё ближе sub-interpreters, на С уже можно пробовать. В Python-коде будет в следующем релизе.
▫️ Наконец закончится возня с кавычками в f-string
▫️ Говорят, хорошо ускорили async код.
➡️ Остальные подробности читаем здесь
#release
Из того что мне приглянулось:
▫️ Всё ближе sub-interpreters, на С уже можно пробовать. В Python-коде будет в следующем релизе.
▫️ Наконец закончится возня с кавычками в f-string
▫️ Говорят, хорошо ускорили async код.
➡️ Остальные подробности читаем здесь
#release
Python.org
Python Release Python 3.12.0
The official home of the Python Programming Language
🔥5👍2