ITDEAL
1.11K subscribers
749 photos
108 videos
11 files
572 links
Разработка комплексных IT решений для бизнеса и частных заказчиков.

Чат: @pybytes_chat

Founder: @lunasantrope
Download Telegram
Работа с асинхронными функциями: `await`, `async with`, `async for` [Часть 3]


📈 Ключевое слово await используется в асинхронном программировании Python для приостановки выполнения корутины до тех пор, пока не завершится ожидаемая асинхронная операция. Это позволяет другим задачам выполняться во время ожидания.


async def fetch_data():
⠀⠀# Представим, что это асинхронный запрос к базе данных
⠀⠀await asyncio.sleep(2) # Задержка имитирует время ожидания данных
⠀⠀return {'data': 1}

async def main():
⠀⠀data = await fetch_data()
⠀⠀print(data)


🔓Асинхронный контекстный менеджер async with используется для гарантии корректного управления асинхронными ресурсами, такими как открытие и закрытие файлов или соединений с базой данных.


async def read_file():
⠀⠀async with aiofiles.open('filename', 'r') as f:
⠀⠀⠀⠀content = await f.read()
⠀⠀⠀⠀print(content)


🔄Асинхронный итератор async for используется для итерации по асинхронно генерируемым последовательностям, например, при постепенном получении данных из веб-сервиса.


async def get_data():
⠀⠀for i in range(5):
⠀⠀⠀⠀await asyncio.sleep(1)
⠀⠀⠀⠀yield i

async def main():
⠀⠀async for item in get_data():
⠀⠀⠀⠀print(item)


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

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥5🔥3👾2
Я тут чуть работаю
Как ваши делишки там?
8🔥5
Создание и управление задачами в "asyncio" [Часть 4]

❤️В асинхронном программировании под задачами понимаются запущенные корутины, которые управляются event loop. С помощью asyncio, можно не только запускать корутины, но и создавать задачи, которые позволяют более гибко управлять асинхронными операциями.


async def count():
⠀⠀print("One")
⠀⠀await asyncio.sleep(1)
⠀⠀print("Two")


🚀Чтобы запустить корутину как задачу, используйте asyncio.create_task(). Это позволит вашей программе продолжать выполнение, не дожидаясь окончания корутины.


async def main():
⠀⠀# Создание задачи
⠀⠀task = asyncio.create_task(count())
⠀⠀print("Counting...")
⠀⠀# Дождемся выполнения задачи
⠀⠀await task


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


async def main():
⠀⠀task = asyncio.create_task(count())
⠀⠀await asyncio.sleep(0.5)
⠀⠀task.cancel()
⠀⠀try:
⠀⠀⠀⠀await task
⠀⠀except asyncio.CancelledError:
⠀⠀⠀⠀print("Task was cancelled!")


❤️‍🔥Создание задач в asyncio открывает новые возможности для более эффективного и гибкого управления асинхронными операциями. В следующей части мы рассмотрим примеры реального использования asyncio и распространенные паттерны.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥4😈2
🚀🌐 Вакансия: User Acquisition Manager / Таргетолог

Привет 👋 Мы ищем опытного специалиста в сфере GameDev, который ранее работал с играми или геймерами.

Требования:

Важно: Вы ранее работали с играми из Steam, либо App Store и Google Play

➡️ Понимание рекламных кабинетов: Google, META, Unity, Twitter, Reddit (Знание дополнительных будет плюсом)
➡️ Запуск и ведение рекламных кампаний, анализ и оптимизация кампаний в реальном времени
➡️ Тестированием креативов, поиском трендов и новых идей, подготовкой ТЗ для моушен-дизайнеров
➡️ Организация тестов новых инструментов и фич на рекламных платформах
➡️ Умение пользоваться инструментами аналитики, умение работать с текстами



Контакты 👉 @spaceitnikita
Please open Telegram to view this post
VIEW IN TELEGRAM
3❤‍🔥3🥰2
🚀🌐 ВАКАНСИЯ: Sales Manager

Мы ищем опытного Sales Manager, готового внести свой вклад в развитие компании и поиск новых клиентов! 🚀


Обязанности и задачи:

➡️ Продажа продуктов и услуг компании (поставка оборудования и ПО)
➡️ Анализ рынка, поиск потенциальных клиентов, выход на ЛПР
➡️ Проведение переговоров на уровне первых лиц компаний, выявление и формирование потребности
➡️Выстраивание и развитие эффективных долгосрочных взаимоотношений с заказчиками
➡️ Организация полного цикла работы с клиентами: от первого контакта до реализации решения и контроля оплаты
➡️ Создание воронок продаж для поиска и привлечения клиентов
➡️ Тесное взаимодействие с различными отделами производства при оценке проекта и подготовке КП
➡️ Инициация проекта после продажи: управление ожиданиями клиента, дебрифинг команды, контроль подписания документов и оплат.


Требования к кандидату:

➡️ Успешный опыт продаж ИТ услуг, инфраструктурных решений, программного обеспечения в B2B, B2G сегменте от 3 лет
➡️ Опыт работы с веб-проектами, понимание современных веб-технологий
➡️ Опыт работы с крупными корпоративными и/или государственными заказчиками
➡️ Уверенные коммуникативные навыки, умение работать в команде, ориентация на результат


Ключевые навыки:

➡️ Навыки презентации
➡️ Деловая коммуникация
➡️ Управление проектами
➡️ Навыки переговоров
➡️ Ведение переговоров
➡️ Знание английского от B2
➡️ Подготовка КП
➡️ Навыки продаж


🤖 Контакты @lunasantrope
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥2
Дескрипторы в Python [Часть 1]

➡️Дескрипторы - мощный инструмент в Python, позволяющий программистам контролировать доступ к атрибутам объекта. Этот механизм широко используется в стандартной библиотеке Python, и понимание его принципов откроет перед вами новые возможности для эффективного и гибкого кодирования.

💡Важность дескрипторов заключается в том, что они дают нам прямой контроль над тем, что происходит, когда атрибут объекта читается, записывается или удаляется. Это достигается за счет реализации специальных методов в классе дескриптора: get, set и delete.

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

class Descriptor:
⠀⠀def __get__(self, instance, owner):
⠀⠀⠀⠀return 'значение'

class MyClass:
⠀⠀descriptor = Descriptor()

obj = MyClass()
print(obj.descriptor) # Выведет: значение


🎓Дескрипторы находят широкое применение в Python. Например, декоратор property - это на самом деле дескриптор, который мы в дальнейшем попробуем воссоздать, чтобы лучше понять его работу и возможности.

❤️‍🔥В следующих постах мы рассмотрим, как создать свой дескриптор с методами get и set, обсудим продвинутые техники их использования и приведем практические примеры, которые помогут вам интегрировать дескрипторы в свои проекты.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥72😈2👍1
🚀🌐 ВАКАНСИЯ: Human Resources (HR)

Мы ищем опытного HR, готового внести свой вклад в развитие компании и поиск новых работников! 🚀
Оклад: 1000-2000$ в месяц 💲


Обязанности и задачи:

➡️ Наём новых сотрудников в компанию.
➡️ Создание кадрового резерва.
➡️ Организация стажировок и адаптация новых кадров.
➡️ Мониторинг и анализ рынка труда.
➡️ Создание системы мотивации. (штрафы/вознаграждения)
➡️ Устранение эмоциональных проблем внутри коллектива.
➡️ Контроль за уровнем знаний работников.
➡️ Организация обучения сотрудников.
➡️ Координирование работы по повышению квалификации.
➡️ Составление трудовых договоров и ведение личных дел сотрудников, выявление КПД.
➡️ Проведение кадровых перестановок.
➡️ Подготовка предложений по распределению бюджетных средств на решение вопросов, связанных с отделом кадров.


Требования к кандидату:

➡️ Понимание ИТ услуг, инфраструктурных решений, программного обеспечения в B2B, B2G сегменте от 3 лет
➡️ Опыт работы с веб-проектами, понимание современных веб-технологий
➡️ Опыт работы с крупными корпоративными и/или государственными заказчиками
➡️ Уверенные коммуникативные навыки, умение работать в команде, ориентация на результат


Ключевые навыки:

➡️ Организация командной работы
➡️ Стрессоустойчивость
➡️ Разработка системы премирования и штрафов
➡️ Навыки презентации
➡️ Деловая коммуникация
➡️ Навыки переговоров
➡️ Знание английского от B2


🤖 Контакты @lunasantrope
Please open Telegram to view this post
VIEW IN TELEGRAM
4🤩2🏆1
Дескрипторы в Python [Часть 2]

😆 Реализация простого дескриптора начинается с понимания методов get и set. Эти методы позволяют контролировать доступ к атрибуту класса.

💡 В примере ниже мы создаем дескриптор для управления атрибутом, который должен быть всегда положительным:


class PositiveNumber:
⠀⠀def __init__(self):
⠀⠀⠀⠀self.value = 0
⠀⠀
⠀⠀def __get__(self, instance, owner):
⠀⠀⠀⠀return self.value
⠀⠀
⠀⠀def __set__(self, instance, value):
⠀⠀⠀⠀if value < 0:
⠀⠀⠀⠀⠀⠀raise ValueError("Значение должно быть положительным")
⠀⠀⠀⠀self.value = value
⠀⠀
class MyClass:
⠀⠀number = PositiveNumber()


🛠 Теперь, если мы попробуем присвоить отрицательное значение атрибуту number, Python выбросит исключение:


my_instance = MyClass()
my_instance.number = -5 # Выбросит ValueError


➡️Использование дескрипторов таким образом позволяет вам точно контролировать значения атрибутов, обеспечивая их корректность и предотвращая неправильное использование.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
4❤‍🔥2😈2
Дескрипторы в Python [Часть 3]

🛠 Теперь давайте рассмотрим более продвинутые возможности дескрипторов: методы delete и set_name. Эти методы позволяют управлять удалением атрибутов и автоматическим именованием.

➡️ Метод delete позволяет нам определить, что происходит при удалении атрибута. В отличие от get и set, его использование менее распространено, но он может быть полезен для управления ресурсами или валидации.


class ProtectedAttribute:
⠀⠀def __init__(self):
⠀⠀⠀⠀self.value = None
⠀⠀
⠀⠀def __delete__(self, instance):
⠀⠀⠀⠀raise AttributeError("Удаление атрибута запрещено")


📌 Метод set_name вызывается автоматически, когда дескриптор присваивается атрибуту класса. Это позволяет дескриптору знать свое имя в классе, что может быть полезно для сообщений об ошибках или логирования.


class NamedAttribute:
⠀⠀def __set_name__(self, owner, name):
⠀⠀⠀⠀self.name = name
⠀⠀
⠀⠀def __set__(self, instance, value):
⠀⠀⠀⠀print(f"Устанавливаем {self.name}")
⠀⠀⠀⠀instance.__dict__[self.name] = value


👀Использование этих методов улучшает гибкость и контроль над поведением атрибутов, обеспечивая более строгую инкапсуляцию и логику ваших классов.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥3💋2
QUIZ: Что выведет данный код?
r = True, True, True == (True, True, True)
print(r)
Anonymous Quiz
39%
True
14%
True, True, False
19%
False
28%
True, True, True
🌭52😈2😐1
Использование "/" и "*" в определениях функций в Python

🧐 Если вы когда-либо заглядывали в исходный код пакетов, возможно, вы видели функции, использующие в своем синтаксисе / или *. Эти символы служат для разграничения аргументов функций на позиционные и ключевые.

💡 Символ / используется для обозначения того, что все аргументы, расположенные до него, являются исключительно позиционными. Это значит, что они не могут быть переданы как ключевые аргументы. После символа / аргументы могут быть переданы как позиционные, так и ключевые.


def func(a, b, /, c, d):
⠀⠀print(a, b, c, d)
⠀⠀
func(1, 2, c=3, d=4) # Работает
func(a=1, b=2, c=3, d=4) # Ошибка!


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

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


def func(a, b, *, c, d):
⠀⠀print(a, b, c, d)
⠀⠀
func(1, 2, c=3, d=4) # Работает
func(1, 2, 3, 4) # Ошибка!


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


def func(a, b, /, c, *, d):
⠀⠀print(a, b, c, d)
⠀⠀
func(1, 2, c=3, d=4) # Работает
func(a=1, b=2, 3, d=4) # Ошибка!
func(1, 2, 3, 4) # Ошибка!


🚀Использование / и * в определениях функций повышает читаемость и ясность кода, особенно в командной разработке. Применяйте их, чтобы сделать интерфейс ваших функций более понятным и защищенным от неправильного использования.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
👀7❤‍🔥42🤨2👍1
Дескрипторы в Python [Часть 4]

🔍В предыдущих частях мы коснулись параметров instance и owner в методах дескриптора, а также особенности вызова метода set. Поговорим о них подробнее.

👥 Параметр instance ссылается на экземпляр класса, через который происходит обращение к атрибуту. Если обращение идет напрямую через класс, а не через экземпляр, instance будет None. Это позволяет дескриптору адаптировать свое поведение в зависимости от того, как именно к нему обращаются.


class Descriptor:
⠀⠀def __get__(self, instance, owner):
⠀⠀⠀⠀if instance is None:
⠀⠀⠀⠀⠀⠀return 'обращение через класс'
⠀⠀⠀⠀return 'обращение через экземпляр'


📈Параметр owner — это сам класс, к которому прикреплен дескриптор. Это позволяет дескриптору иметь информацию о классе, даже если доступ к атрибуту осуществляется через экземпляр.

⚠️Особый случай с методом set: если вы пытаетесь назначить значение дескриптору напрямую через класс, а не через его экземпляр, метод set не будет вызван. Это связано с тем, что в таком случае вы фактически перезаписываете сам дескриптор в классе, а не взаимодействуете с его методом set.


class MyClass:
⠀⠀descriptor = Descriptor()
⠀⠀
MyClass.descriptor = 'новое значение' # __set__ не вызывается


💥 Это важный момент для понимания того, как Python работает с дескрипторами и какие действия могут "обойти" логику, заданную в дескрипторе.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥4👍3🗿1
Дескрипторы в Python [Заключительная часть]

🔤 В этом финальном посте мы создадим PropertyDescriptor, аналог стандартной функции property, для глубокого понимания дескрипторов.

🔍 Важные аспекты нашего PropertyDescriptor:

- __init__: принимает функции для получения и установки значения, аналогично property.
- __get__: возвращает значение, используя функцию получения, если дескриптор обращается через экземпляр.
- __set__: устанавливает значение с помощью функции установки, предоставляя дополнительную логику валидации или трансформации.

Минимальный пример:


class MyClass:
⠀⠀my_attr = PropertyDescriptor(get_my_attr, set_my_attr)


Это упрощенное представление того, как мы хотим контролировать доступ к атрибуту my_attr.

📌 Детальная реализация и объяснения будут представлены в прикрепленном изображении.

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

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥33🍾2
🚀🌐 ВАКАНСИЯ: Human Resources (HR)

Мы ищем опытного HR, готового внести свой вклад в развитие компании и поиск новых клиентов! 🚀
Оклад: 1000-2000$ в месяц 💲


Обязанности и задачи:

➡️ Наём новых сотрудников в компанию.
➡️ Создание кадрового резерва.
➡️ Организация стажировок и адаптация новых кадров.
➡️ Мониторинг и анализ рынка труда.
➡️ Создание системы мотивации. (штрафы/вознаграждения)
➡️ Устранение эмоциональных проблем внутри коллектива.
➡️ Контроль за уровнем знаний работников.
➡️ Организация обучения сотрудников.
➡️ Координирование работы по повышению квалификации.
➡️ Составление трудовых договоров и ведение личных дел сотрудников, выявление КПД.
➡️ Проведение кадровых перестановок.
➡️ Подготовка предложений по распределению бюджетных средств на решение вопросов, связанных с отделом кадров.


Требования к кандидату:

➡️ Понимание ИТ услуг, инфраструктурных решений, программного обеспечения в B2B, B2G сегменте от 3 лет
➡️ Опыт работы с веб-проектами, понимание современных веб-технологий
➡️ Опыт работы с крупными корпоративными и/или государственными заказчиками
➡️ Уверенные коммуникативные навыки, умение работать в команде, ориентация на результат


Ключевые навыки:

➡️ Организация командной работы
➡️ Стрессоустойчивость
➡️ Разработка системы премирования и штрафов
➡️ Навыки презентации
➡️ Деловая коммуникация
➡️ Навыки переговоров
➡️ Знание английского от B2


🤖 Контакты @lunasantrope
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥1🏆1
Обработка исключений в Python [Часть 1]

💥 Обработка исключений - ключевой элемент написания надёжного кода на Python. Она позволяет вашей программе адекватно реагировать на ошибки и продолжать работу, не прерываясь при первом же сбое. Это особенно важно в больших проектах и системах, где стабильность - приоритет.

🛠 Простейший пример обработки исключения включает в себя блоки try и except:


try:
⠀⠀print("Попробуем это выполнить")
⠀⠀# Код, который может вызвать исключение
⠀⠀
except Exception as e:
⠀⠀print(f"Произошла ошибка: {e}")


💡 В блоке try помещается код, который может породить исключение, а в блоке except - код, который должен выполниться, если в блоке try произошла ошибка. Это позволяет программе элегантно обрабатывать потенциальные ошибки.

🔤 Важно понимать, что исключения - это не всегда "ошибки" в обычном понимании. Это могут быть ситуации, когда программа должна изменить своё поведение или предупредить пользователя, например, о неверно введённых данных.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥3👀2
Ого, это что, новый обзор???
7🔥2😨2
Обработка исключений в Python [Часть 3]

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


try:
⠀⠀# Код, который может вызвать разные исключения
except (TypeError, ValueError) as e:
⠀⠀print(f"Произошла ошибка: {e}")
⠀⠀
except Exception as e:
⠀⠀print(f"Неизвестная ошибка: {e}")


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


class MyCustomError(Exception):
⠀⠀def __init__(self, message="Моя ошибка"):
⠀⠀⠀⠀self.message = message
⠀⠀⠀⠀super().__init__(self.message)
⠀⠀
try:
⠀⠀raise MyCustomError("Что-то пошло не так")
⠀⠀
except MyCustomError as e:
⠀⠀print(e)


❤️‍🔥 Определение собственных классов исключений позволяет более точно указать, какие ошибки могут возникнуть в вашем коде, и как их следует обрабатывать, делая ваш код более интуитивно понятным для других разработчиков.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥5🍓3👍1
LBYL vs EAFP в Python [Часть 1]

🔤 В мире Python существуют две философии программирования при работе с возможными ошибками: LBYL (Look Before You Leap) и EAFP (Easier to Ask for Forgiveness than Permission). Эти подходы крайне важны для понимания и правильного использования обработки исключений.

📌 LBYL (Look Before You Leap) - это подход, при котором перед выполнением операции вы проверяете все возможные проблемы. Например, прежде чем читать файл, вы проверяете, существует ли он:


import os
if os.path.exists("file.txt"):
⠀⠀with open("file.txt") as file:
⠀⠀⠀⠀data = file.read()


📌 EAFP (Easier to Ask for Forgiveness than Permission) - подход, согласно которому вы выполняете операцию напрямую, ожидая, что она может не сработать, и затем обрабатываете возможные исключения:


try:
⠀⠀with open("file.txt") as file:
⠀⠀⠀⠀data = file.read()
except FileNotFoundError:
⠀⠀print("Файл не найден")


💬 В Python часто предпочитают EAFP из-за его соответствия духу языка и способности эффективно обрабатывать неожиданные ситуации без предварительной проверки всех условий.

🔍 Оба подхода имеют свои места и могут использоваться в зависимости от ситуации и предпочтений программиста. В следующем посте мы рассмотрим, когда и почему стоит использовать каждый из них.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥73💊3
LBYL vs EAFP в Python [Часть 2]

🤔 Когда использовать LBYL и EAFP? В Python оба подхода имеют своё место, но важно понимать, когда каждый из них является наилучшим выбором.

🛡 LBYL (Look Before You Leap) обычно используется в средах, где состояния изменяются редко или когда проверки не требуют значительных ресурсов. Этот подход может сделать код более читаемым для тех, кто привык к традиционному программированию. Однако, в многопоточных средах LBYL может привести к гонкам за состояние, поскольку состояние может измениться между проверкой и выполнением.

🔤 EAFP (Easier to Ask for Forgiveness than Permission) рекомендуется в Python, особенно в многопоточных и сетевых приложениях, где состояние может измениться в любой момент. Этот подход также считается более "pythonic", поскольку часто приводит к более чистому и эффективному коду.


# LBYL подход
if key in some_dict:
⠀⠀result = some_dict[key]
else:
⠀⠀result = "Значение не найдено"
⠀⠀
# EAFP подход
try:
⠀⠀result = some_dict[key]
except KeyError:
⠀⠀result = "Значение не найдено"


📊 Выбор между LBYL и EAFP зависит от многих факторов, включая читаемость кода, вероятность возникновения исключений и оверхед на проверки. В целом, EAFP может быть более подходящим в Python из-за его способности эффективно обрабатывать исключения и поддерживать чистоту кода.

🔝 В заключение, выбор между LBYL и EAFP должен основываться на вашем контексте и требованиях к программе. Python дает вам гибкость выбора, позволяя писать эффективный и легко читаемый код.

🔝 PyBytes Media | ✉️ Telegram / 📷 Instagram / 📈Mentor Service
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥33🍾2
Разбавить контент канала IT новостями?
Anonymous Poll
52%
Да, слишком много учебы
48%
Нет, только знания
This media is not supported in your browser
VIEW IN TELEGRAM
💡 Думаю мало кто знает, но я как настоящий IT-шник решил попробовать поездить по миру и поискать местечко для постоянной жизни себе

Показывать вам места где я бываю? Интересно видеть немного оффлайн-жизни?

🔥 - Да
❤️ - Да
👍🏽 - Да
🔥418👍4❤‍🔥2