Расширим знания о "магических" файлах. 🧙♀️
Допустим у нас есть каталог
Первый уровень магии
Создаём пустой файл
и далее вызывать
Второй уровень магии
В файл
мы автоматически запустим содержимое файла «инит».
Например, файл содержит строку кода:
Добавляем в директорию
и тут же выполняется содержимое «мейна». Высшая магия позволяет уйти от импорта и от интерпретатора Python. Теперь мы работаем с питоновским каталогом непосредственно из нашей ОС.
Например «мейн» содержит код:
Допустим у нас есть каталог
project с файлами begin.py, work.py и другими. Большинство Python разработчиков знают, что добавление пустого файла __init__.py в директорию проекта превращает её в питоновский пакет.Первый уровень магии
Создаём пустой файл
__init__.py Теперь мы можем написать в коде:import project и далее вызывать
project.begin или project.work.Второй уровень магии
В файл
__init__.py помещаем нужный нам код. При импорте директории:import project мы автоматически запустим содержимое файла «инит».
Например, файл содержит строку кода:
print("Hello from init")
После импорта в другом файле с расширением py или в интерпретаторе, мы увидим вывод в консоли: Hello from initВысший уровень магии
Добавляем в директорию
project файл __main__.py Теперь Python может запускать project как исполняемый файл. Пишем в консоли операционной системы(!):python project и тут же выполняется содержимое «мейна». Высшая магия позволяет уйти от импорта и от интерпретатора Python. Теперь мы работаем с питоновским каталогом непосредственно из нашей ОС.
Например «мейн» содержит код:
print(f"Hello from {__name__}.py")
При запуске через ОС увидим в консоли:Hello from main.pyПриём с «инит» и «мейн» позволяет автоматизировать запуск Python скриптов по расписанию, упростить процесс первичной инициализации и вообще облегчает работу разработчика. 😎
👍14❤4
Сталкивались ли вы с ситуацией, когда огромный словарь (список, JSON) невозможно нормально прочитать? Глазами, а не из-за проблем с доступом. 👀
Берём на вооружение "заикающийся принт". 👇
Двойное "P" не заикание, а сокращение. Pretty print. Красоту он даёт при выводе словарей (и не только их).
Пример 1. Словарь
Вывод:
Обратите внимание, что при выводе ключи словаря сортируются в алфавитном порядке.
Пример 2. Словарь со списком словарей
Вывод:
Берём на вооружение "заикающийся принт". 👇
from pprint import pprint
Двойное "P" не заикание, а сокращение. Pretty print. Красоту он даёт при выводе словарей (и не только их).
Пример 1. Словарь
data_dct = {"text": "one", "new_text": 22, "other_text": [1, 2, 3], "any_text": "any_text", "data_object": None}
pprint(data_dct)Вывод:
{'any_text': 'any_text',
'data_object': None,
'new_text': 22,
'other_text': [1, 2, 3],
'text': 'one'}Обратите внимание, что при выводе ключи словаря сортируются в алфавитном порядке.
Пример 2. Словарь со списком словарей
data = {"complet":[{"id":286050,"score":10,"username":"Юрий","title":"Деревья","chapter":18,"seen":True},{"id":255762,"score":5,"username":"Алексей","title":"Ветви","chapter":8,"seen":True},{"id":284531,"score":8,"username":"Алексей","title":"Листья","chapter":7,"seen":True},{"id":845560,"score":3,"username":"Юрий","title":"Корни","chapter":27,"seen":False}],"pending":[{"id":282400,"score":5,"username":"Владимир","title":"Трава","chapter":3,"seen":True},{"id":35388,"score":35,"username":"Вероника","title":"Кусты","chapter":6,"seen":False},{"id":80718,"score":7,"username":"Юрий","title":"Грибы","chapter":6,"seen":True}],"complet_count":4,"pending_count":3}
pprint(data)Вывод:
{'complet': [{'chapter': 18,
'id': 286050,
'score': 10,
'seen': True,
'title': 'Деревья',
'username': 'Юрий'},
{'chapter': 8,
'id': 255762,
'score': 5,
'seen': True,
'title': 'Ветви',
'username': 'Алексей'},
{'chapter': 7,
'id': 284531,
'score': 8,
'seen': True,
'title': 'Листья',
'username': 'Алексей'},
{'chapter': 27,
'id': 845560,
'score': 3,
'seen': False,
'title': 'Корни',
'username': 'Юрий'}],
'complet_count': 4,
'pending': [{'chapter': 3,
'id': 282400,
'score': 5,
'seen': True,
'title': 'Трава',
'username': 'Владимир'},
{'chapter': 6,
'id': 35388,
'score': 35,
'seen': False,
'title': 'Кусты',
'username': 'Вероника'},
{'chapter': 6,
'id': 80718,
'score': 7,
'seen': True,
'title': 'Грибы',
'username': 'Юрий'}],
'pending_count': 3}👍18🔥4
Python важны отступы вначале для верной интерпретации кода. Человеку, читающему код на Python важен моноширинный шрифт, чтобы верно понять код.
Несколько lifehack'ов для тех, кто любит выкладывать Python код в Телеграм.
1. Одинарный апостроф ➡️ ` ⬅️ до и после одной строки кода сделает её (строку) моноширинной.
2. Три апострофа ➡️ ``` ⬅️ строкой выше и строкой ниже текста делают его моноширинным, как код на Python с отступами.
3 = 1 + 2. Если выделить набранный вами код, можно вызвать контекстное меню и оформить его как моно. Получаем эффект двух первых пунктов.
Бонусный лайфхак. Если развернуть телефон горизонтально, длинные строки Python кода станут более читаемыми. Проверьте на прошлом посте с примерами pprint.
Несколько lifehack'ов для тех, кто любит выкладывать Python код в Телеграм.
1. Одинарный апостроф ➡️ ` ⬅️ до и после одной строки кода сделает её (строку) моноширинной.
2. Три апострофа ➡️ ``` ⬅️ строкой выше и строкой ниже текста делают его моноширинным, как код на Python с отступами.
3 = 1 + 2. Если выделить набранный вами код, можно вызвать контекстное меню и оформить его как моно. Получаем эффект двух первых пунктов.
Бонусный лайфхак. Если развернуть телефон горизонтально, длинные строки Python кода станут более читаемыми. Проверьте на прошлом посте с примерами pprint.
🔥6👍1
Случайно наткнулся на такую строчку кода у коллег в учебном примере.
О, нет! Мои глаза! Два сушёных питона в одной строке кода. 😱
Почему? Рассказываю.
1. lambda - анонимная функция языка Python. Она является синтаксическим сахаром и позволяет записать короткую функцию в одну строку без ключевого слова def и задания имени.
В примере анонимная функция вместо вызова-использования присваивается переменной. Мы задаём имя анонимной функции. Общество анонимных лямбдоведов нервно курит в сторонке. 😭
Как починить? Явным уходом от анонимности
2. Функции присваивается имя
Как починить? Добавлением символ подчеркивания после имени. (Совет не мой, а Гвидо 🤓).
sum = lambda x, y: x + yО, нет! Мои глаза! Два сушёных питона в одной строке кода. 😱
Почему? Рассказываю.
1. lambda - анонимная функция языка Python. Она является синтаксическим сахаром и позволяет записать короткую функцию в одну строку без ключевого слова def и задания имени.
В примере анонимная функция вместо вызова-использования присваивается переменной. Мы задаём имя анонимной функции. Общество анонимных лямбдоведов нервно курит в сторонке. 😭
Как починить? Явным уходом от анонимности
def sum(x, y):
return x + y2. Функции присваивается имя
sum. Точно такое же имя у встроенной функции для подсчёта суммы. Мы перезаписали функцию из buildings. А это плохая привычка. Если не позаботиться о сокрытии в пространстве имён, у коллег по коду сломаются все их вызовы sum() в вашем общем проекте.Как починить? Добавлением символ подчеркивания после имени. (Совет не мой, а Гвидо 🤓).
def sum_(x, y):
return x + y👍11😱2
Пост о программировании без единой строчки кода.
Однажды мне надо было заполнить данные по более чем тысяче изделиям за каждый из 365 дней года:
Если заполнять ячейку таблицы за секунду, за рабочий день получится:
Интересно, есть люди, которые способны весь рабочий день нажимать кнопки клавиатуры без остановки?
Получается, что работы выпало на
Пара-тройка часов программирования и табличка стала заполняться сама, считая нужные значения, с проверками и прочими нюансами заполнения.
А теперь самое крутое. В кабинет заходит начальник и видит как я гуляю с чашкой кофе. На вопрос: "Ты чего не сидишь за компом? Работай!", киваю в сторону монитора.
Видели бы вы лицо начальника в тот момент. Премию мне не дали. Но и новыми задачами не грузили. Всё же задание было не из лёгких. 😉
Были ли у вас подобные ситуации? Когда навык программирования экономил вам время и удивлял других.
Однажды мне надо было заполнить данные по более чем тысяче изделиям за каждый из 365 дней года:
1000 × 365 = 365000 записейЕсли заполнять ячейку таблицы за секунду, за рабочий день получится:
8 × 60 × 60 = 28800 записейИнтересно, есть люди, которые способны весь рабочий день нажимать кнопки клавиатуры без остановки?
Получается, что работы выпало на
365000 ÷ 28000 ≈ 13 дней ≈ 3 рабочие неделиПара-тройка часов программирования и табличка стала заполняться сама, считая нужные значения, с проверками и прочими нюансами заполнения.
А теперь самое крутое. В кабинет заходит начальник и видит как я гуляю с чашкой кофе. На вопрос: "Ты чего не сидишь за компом? Работай!", киваю в сторону монитора.
Видели бы вы лицо начальника в тот момент. Премию мне не дали. Но и новыми задачами не грузили. Всё же задание было не из лёгких. 😉
Были ли у вас подобные ситуации? Когда навык программирования экономил вам время и удивлял других.
👍7
Тернарный оператор
Возьмём простую задачу, например сохранять в список четные числа. А если число нечётное, сохранять следующее по порядку чётное.
Было
Стало
А теперь два примера использования тернарного оператора. Первый:
И второй пример:
Оба варианта дают одинаковый результат, но...
У кого какие мысли про «но»? Свои в продолжении поста завтра утром. 😉
Возьмём простую задачу, например сохранять в список четные числа. А если число нечётное, сохранять следующее по порядку чётное.
Было
[2, 3, 4, 5]Стало
[2, 4, 4, 6]А теперь два примера использования тернарного оператора. Первый:
data = []
for x in range(10):
data.append(x) if x % 2 == 0 else data.append(x + 1)
print(data)
И второй пример:
data = []
for x in range(10):
data.append(x if x % 2 == 0 else x + 1)
print(data)
Оба варианта дают одинаковый результат, но...
У кого какие мысли про «но»? Свои в продолжении поста завтра утром. 😉
🤔4👍3
Но заключается в том, что первый вариант возвращает вызов метода append с разными аргументами. Так себе идея. 😢
Во втором случае тернарный оператор возвращает одно из двух возможных значений, которое передается как аргумент в метод append
Подобная запись не только короче. Мы явно указываем цель написания строки кода - использовать append для добавления элемента. Читать такое легче и понятнее.
Что касается Python - он тоже строит более короткий маршрут реализации, а следовательно выполняет задачу быстрее. 🏃♂💨
data.append(x) if x % 2 == 0 else data.append(x + 1)Во втором случае тернарный оператор возвращает одно из двух возможных значений, которое передается как аргумент в метод append
data.append(x if x % 2 == 0 else x + 1)Подобная запись не только короче. Мы явно указываем цель написания строки кода - использовать append для добавления элемента. Читать такое легче и понятнее.
Что касается Python - он тоже строит более короткий маршрут реализации, а следовательно выполняет задачу быстрее. 🏃♂💨
🔥4
Какая разница между потоком и процессом?
На современных ПК запуск вашей любимой программы приводит к созданию процесса с одним потоком внутри. Можно представить, что процесс - дорога, а поток - количество полос на этой дороге. Обычно по однополосной дороге движется один авто - выполняется ваш код. Получается, что для более быстрого выполнения программы можно создать несколько полос-потоков с авто на каждой? 🤔 Пусть едут парраллельно. Или создать несколько дорог-процессов? Процессы ведь могут решать параллельные задачи.
Но есть одна особенность. 🤓 Представим одноядерный процессор. Он выполняет код нескольких программ одновременно, потому что очень быстро переключается между ними. Сдивнул на пару метров вперёд машину на одной дороге процессе, потом на другой, на третей и т.д. А если внутри процесса несколько потоков, то и тут каждая машина движется по очереди. Одна в движении, остальные стоят.
Если же у процессора несколько ядер, процессы на разных ядрах действительно могут выполняться одновременно. А вот потоки внутри процесса как двигались по очереди, так и остались псевдоодновременными. 😉
#многопоточность
На современных ПК запуск вашей любимой программы приводит к созданию процесса с одним потоком внутри. Можно представить, что процесс - дорога, а поток - количество полос на этой дороге. Обычно по однополосной дороге движется один авто - выполняется ваш код. Получается, что для более быстрого выполнения программы можно создать несколько полос-потоков с авто на каждой? 🤔 Пусть едут парраллельно. Или создать несколько дорог-процессов? Процессы ведь могут решать параллельные задачи.
Но есть одна особенность. 🤓 Представим одноядерный процессор. Он выполняет код нескольких программ одновременно, потому что очень быстро переключается между ними. Сдивнул на пару метров вперёд машину на одной дороге процессе, потом на другой, на третей и т.д. А если внутри процесса несколько потоков, то и тут каждая машина движется по очереди. Одна в движении, остальные стоят.
Если же у процессора несколько ядер, процессы на разных ядрах действительно могут выполняться одновременно. А вот потоки внутри процесса как двигались по очереди, так и остались псевдоодновременными. 😉
#многопоточность
👍9
Прежде чем рассказать о потоках в Python, несколько абзацев о потоках в ОС. Располагайтесь удобнее. История одного предприятия. 🤓
Итак, у нас есть швейный цех - процесс. 🏭
Внутри него есть несколько сотрудников - потоки. 👨🔧
А всё содержимое цеха доступно каждому сотруднику, здание же одно на всех. 🤝
Основную часть времени сотрудники залипают в телефоны и ничего не делаю. Разве что мистер Контроль время от времени поглядывает на входную дверь в ожидании клиентов. Два брата близнеца по кличке Модели косятся на стойку заказов, а старичок Видок любуется пустой полкой готовых заказов.
Открывает дверь, заходит клиент. Контроль срывается с места и начинает снимать примерки, уточнять фасон, ткань и прочие детали. Пока он суетится остальные залипают в телефоны и боятся пошевелиться. Разве что Контроль в какой-то момент задумался о допустимых узорах, да так, что застыл на месте. В этот момент один из близнецов Моделей метнулся к столу заказов, увидел что пусто и снова залип в мобилку.
Заказ принят, заявка заполнена, один из близнецов не обращая внимания на застывшего мистера Контроля бежит в соседнее здание-процесс на дальний склад материалов. Там бабушка DеBи по кличке Мускул забирает список и Модельный близнец снова залипает в телефон.
Мистер Контроль снимает очередные примерки с нового клиента. В момент, когда клиент уточняет свои пожелания Контроль даже не шевелится. Зато в эти мгновения слышно как в рабочей зоне близнец Модель шьёт первый костюм.
Первый заказ падает на полку к готовым. Модельный близнец не обращая внимания на своего брата-близница, проверяет стойку заказов. Мистер Контроль как раз успел разместить заказ второго клиента. Но прежде чем забрать второй заказ Модель о чём-то задумывается в оцепенении. В этот момент старик Видок ухитряется передать огромный тяжёлый свёрток с первым заказом клиенту. И только когда посылка выдана, а Видок уселся на место, близнец хватает заказ и убегает на склад к бабуле Мускул.
Такая вот веселая работа в процессном цеху у ребят потоков. А самое любопытное, что работает всегда один. Остальные в это время бездельничают, думая о чём-то своём. 😉
#многопоточность
Итак, у нас есть швейный цех - процесс. 🏭
Внутри него есть несколько сотрудников - потоки. 👨🔧
А всё содержимое цеха доступно каждому сотруднику, здание же одно на всех. 🤝
Основную часть времени сотрудники залипают в телефоны и ничего не делаю. Разве что мистер Контроль время от времени поглядывает на входную дверь в ожидании клиентов. Два брата близнеца по кличке Модели косятся на стойку заказов, а старичок Видок любуется пустой полкой готовых заказов.
Открывает дверь, заходит клиент. Контроль срывается с места и начинает снимать примерки, уточнять фасон, ткань и прочие детали. Пока он суетится остальные залипают в телефоны и боятся пошевелиться. Разве что Контроль в какой-то момент задумался о допустимых узорах, да так, что застыл на месте. В этот момент один из близнецов Моделей метнулся к столу заказов, увидел что пусто и снова залип в мобилку.
Заказ принят, заявка заполнена, один из близнецов не обращая внимания на застывшего мистера Контроля бежит в соседнее здание-процесс на дальний склад материалов. Там бабушка DеBи по кличке Мускул забирает список и Модельный близнец снова залипает в телефон.
Мистер Контроль снимает очередные примерки с нового клиента. В момент, когда клиент уточняет свои пожелания Контроль даже не шевелится. Зато в эти мгновения слышно как в рабочей зоне близнец Модель шьёт первый костюм.
Первый заказ падает на полку к готовым. Модельный близнец не обращая внимания на своего брата-близница, проверяет стойку заказов. Мистер Контроль как раз успел разместить заказ второго клиента. Но прежде чем забрать второй заказ Модель о чём-то задумывается в оцепенении. В этот момент старик Видок ухитряется передать огромный тяжёлый свёрток с первым заказом клиенту. И только когда посылка выдана, а Видок уселся на место, близнец хватает заказ и убегает на склад к бабуле Мускул.
Такая вот веселая работа в процессном цеху у ребят потоков. А самое любопытное, что работает всегда один. Остальные в это время бездельничают, думая о чём-то своём. 😉
#многопоточность
👏8😱2😁1🎉1
Пришли время рассказать вам страшную тайну о GIL* 😱
*GIL (Global Interpreter Lock) - разрешённая на территории CPython* глобальная блокировка интерпретатора.
*CPython - эталонная версия Python, написанная Гвидо на языке Си и используемая большинством питонистов. Сайт python.org именно о CPython.
Правда в том, что GIL не делает код на Python медленным. 🦾 Замедляют его кривые ручёнки программистов. 🤲
Представьте кухню где работают два сотрудника-потока. Один нарезает продукты. Второй замешивает из них салаты. А ещё есть шеф-повор в виде ОС, который заведует переключением между потоками. На кого посмотрел, тот тут же кидается работать. Остальные в это время отдыхают.
Ситуация без GIL.
Первый сотрудник взял 3 огурца и стал их нарезать под взглядом шефа. Нарезал пару и шеф переключился на второго. Второй сотрудник хватает доску и высыпает и нарезанное и целый огурец в салатницу. Шеф смотрит на первого и тот в ужасе нарезает столешницу - огурцы и доску у него отняли.
Как итог салат не нарезан, стол испорчен.
Ситуация с GIL.
Первый сотрудник взял 3 огурца и стал их нарезать под взглядом шефа. Нарезал пару и шеф переключился на второго. Второй сотрудник говорит шефу, что пока рано и тот снова переключается на первого. Покрошив все огурцы первый поток отдыхает и шеф недолго думая заставляет второго замешивать салат. Снова взгляд на первого, а тот ему: "Без доски для нарезки работать не буду. Жду, пока второй вернёт". И шеф возвращается ко второму, чтобы дождаться возврата доски для нарезки.
В итоге салат готов, а ребята благодаря GIL работали только тогда, когда могли это делать не мешая другому. 👫
GIL делает потоконебезопасный Python безопасным, запрещая запускать процесс в то время, когда другому важно закончить своё дело. 🤓
*GIL (Global Interpreter Lock) - разрешённая на территории CPython* глобальная блокировка интерпретатора.
*CPython - эталонная версия Python, написанная Гвидо на языке Си и используемая большинством питонистов. Сайт python.org именно о CPython.
Правда в том, что GIL не делает код на Python медленным. 🦾 Замедляют его кривые ручёнки программистов. 🤲
Представьте кухню где работают два сотрудника-потока. Один нарезает продукты. Второй замешивает из них салаты. А ещё есть шеф-повор в виде ОС, который заведует переключением между потоками. На кого посмотрел, тот тут же кидается работать. Остальные в это время отдыхают.
Ситуация без GIL.
Первый сотрудник взял 3 огурца и стал их нарезать под взглядом шефа. Нарезал пару и шеф переключился на второго. Второй сотрудник хватает доску и высыпает и нарезанное и целый огурец в салатницу. Шеф смотрит на первого и тот в ужасе нарезает столешницу - огурцы и доску у него отняли.
Как итог салат не нарезан, стол испорчен.
Ситуация с GIL.
Первый сотрудник взял 3 огурца и стал их нарезать под взглядом шефа. Нарезал пару и шеф переключился на второго. Второй сотрудник говорит шефу, что пока рано и тот снова переключается на первого. Покрошив все огурцы первый поток отдыхает и шеф недолго думая заставляет второго замешивать салат. Снова взгляд на первого, а тот ему: "Без доски для нарезки работать не буду. Жду, пока второй вернёт". И шеф возвращается ко второму, чтобы дождаться возврата доски для нарезки.
В итоге салат готов, а ребята благодаря GIL работали только тогда, когда могли это делать не мешая другому. 👫
GIL делает потоконебезопасный Python безопасным, запрещая запускать процесс в то время, когда другому важно закончить своё дело. 🤓
👍7
Внезапно узнал, что многие начинающие и немногие продолжающие ITшники не знают что такое операции ввода/вывода. Те самые, которые I/O.
Забавно было услышать от питониста, что I - функция input(), а O - функция print(). Вы что, про сенсорные экраны совсем забыли? 🤔
Ладно, про экраны пошутил. Давайте разберёмся.
I/O - любые операции ввода и вывода данных, которые выходят за рамки материнской платы с процессором и оперативной памятью.
Помимо привычных клавиатуры и экрана (а так же сенсорного экрана) к I/O относятся и прочие периферийные устройся, например сканер и принтер, компьютерная мышка. 🖨
Любые операции с файлами тоже I/O. Не важно файлы на диске, флешке, карте памяти или где-то ещё. 💾
Всё, что передается по каналам связи тоже I/O: сайты в интернете, просмотр фильма на Smart TV, фоточки в облаке и даже пересылка видео с котиками с телефона на планшет через домашний роутер. 🌐
Отдельно отнесу к I/O работу с базами данных. Если база на том же ПК, что и программа отправляющая запросы, БД всё равно работает с файлами. А иногда это ещё и работа с файлами по сети. 🗄
И стоит упомянуть такое исключение как DB in memory. С одной стороны это взаимодействие одного процесса с другим внутри троицы: мамка, проц, оператива. С другой - ввод и вывод данных между программой и БД. 🔄
Лично я считаю это самым быстрым I/O взаимодействием. Соглашаться с последним пунктом не обязательно, как и спорить. 😇
В целом же надеюсь, что прояснил ситуацию с I/O и буду реже встречаться с зависающим после обновления юным дарованием сервером, который блокирует всё и вся в ожидании ответа из другой точки земного шара 🤦♂
Забавно было услышать от питониста, что I - функция input(), а O - функция print(). Вы что, про сенсорные экраны совсем забыли? 🤔
Ладно, про экраны пошутил. Давайте разберёмся.
I/O - любые операции ввода и вывода данных, которые выходят за рамки материнской платы с процессором и оперативной памятью.
Помимо привычных клавиатуры и экрана (а так же сенсорного экрана) к I/O относятся и прочие периферийные устройся, например сканер и принтер, компьютерная мышка. 🖨
Любые операции с файлами тоже I/O. Не важно файлы на диске, флешке, карте памяти или где-то ещё. 💾
Всё, что передается по каналам связи тоже I/O: сайты в интернете, просмотр фильма на Smart TV, фоточки в облаке и даже пересылка видео с котиками с телефона на планшет через домашний роутер. 🌐
Отдельно отнесу к I/O работу с базами данных. Если база на том же ПК, что и программа отправляющая запросы, БД всё равно работает с файлами. А иногда это ещё и работа с файлами по сети. 🗄
И стоит упомянуть такое исключение как DB in memory. С одной стороны это взаимодействие одного процесса с другим внутри троицы: мамка, проц, оператива. С другой - ввод и вывод данных между программой и БД. 🔄
Лично я считаю это самым быстрым I/O взаимодействием. Соглашаться с последним пунктом не обязательно, как и спорить. 😇
В целом же надеюсь, что прояснил ситуацию с I/O и буду реже встречаться с зависающим после обновления юным дарованием сервером, который блокирует всё и вся в ожидании ответа из другой точки земного шара 🤦♂
👍8
Немного питоновской магии в ленту 🧙♂️
На входе словарь на три разных ключа и значения, на выходе всего одна пара ключ-значение в словаре. Да ещё и значение третье, а ключ первый. Магия, никак не иначе.
Через сутки раскрою секрет волшебства. У кого есть свои версии фокуса, welcome to comments. 🤗
>>> d = {1: "раз", 1.0: "два", True: "три"}
>>> d
{1: "три"}На входе словарь на три разных ключа и значения, на выходе всего одна пара ключ-значение в словаре. Да ещё и значение третье, а ключ первый. Магия, никак не иначе.
Через сутки раскрою секрет волшебства. У кого есть свои версии фокуса, welcome to comments. 🤗
👍5🤔5
Пришло время раскрыть тайну. Магический секрет словаря кроется в следующем.
1. Ничего не происходит мгновенно. Python читает код слева направо. В этом конкретном случае ключи и значения попадают в словарь по очереди, раз, два, три.
2. При добавлении новой пары key-value вычисляется хэш ключа. Он же индекс для хранения пары. Если в ячейке пусто, добавляем новую пару в словарь. А если ячейка занята, обновляем только значение для существующего ключа. Логично же экономить время и не обновлять ранее добавленный ключ.
3. А теперь магия
Для Python все три значения одинаковы по значению и по хэшу.
Впрочем, это три совершенно разных объекта в памяти. Но это уже другая история 🤓
P.S. Не путайте хэш и кэш, pls. 🙏
1. Ничего не происходит мгновенно. Python читает код слева направо. В этом конкретном случае ключи и значения попадают в словарь по очереди, раз, два, три.
2. При добавлении новой пары key-value вычисляется хэш ключа. Он же индекс для хранения пары. Если в ячейке пусто, добавляем новую пару в словарь. А если ячейка занята, обновляем только значение для существующего ключа. Логично же экономить время и не обновлять ранее добавленный ключ.
3. А теперь магия
>>> hash(1)
1
>>> hash(1.0)
1
>>> hash(True)
1
>>> 1 == 1.0 == True
True
Для Python все три значения одинаковы по значению и по хэшу.
Впрочем, это три совершенно разных объекта в памяти. Но это уже другая история 🤓
P.S. Не путайте хэш и кэш, pls. 🙏
👏11
А давайте поговорим про однострочники.
Что это за зверь диковинный? Это попытка решить задачу в одну строку зачастую пренебрегая читаемостью, отлаживаемостью кода.
Конечно же есть хорошие однострочники, Python Style one love 💕 Например обмен переменных местами, генераторные выражения или списковые включения, они же listcomp:
Но часто однострочники уместны лишь на соревнованиях по написанию кода в минимум строк. В реальных же ситуациях они скорее выдают в разработчике новичка, который показывает не те знания и/или не умеет работать в команде. 😱
А теперь сделаем вид, что у нас соревнования однострочников. 🤓 И необходимо написать FizzBuzz. Если не слышали, то это одна из задач с собеседований. Вывести числа от 1 до 100. Если число кратно 3, то вместо него вывести Fizz. Если кратно 5 - Buzz. А если одновременно кратно 3 и 5, то FizzBuzz.
Ловите Python решение в одну строку ниже. И удачных вам собеседований. 😉
Что это за зверь диковинный? Это попытка решить задачу в одну строку зачастую пренебрегая читаемостью, отлаживаемостью кода.
Конечно же есть хорошие однострочники, Python Style one love 💕 Например обмен переменных местами, генераторные выражения или списковые включения, они же listcomp:
a, b = b, a
gen = (i for i in range(x, y, z) if i not in data)
lst = [*range(n)]
Но часто однострочники уместны лишь на соревнованиях по написанию кода в минимум строк. В реальных же ситуациях они скорее выдают в разработчике новичка, который показывает не те знания и/или не умеет работать в команде. 😱
А теперь сделаем вид, что у нас соревнования однострочников. 🤓 И необходимо написать FizzBuzz. Если не слышали, то это одна из задач с собеседований. Вывести числа от 1 до 100. Если число кратно 3, то вместо него вывести Fizz. Если кратно 5 - Buzz. А если одновременно кратно 3 и 5, то FizzBuzz.
Ловите Python решение в одну строку ниже. И удачных вам собеседований. 😉
print(*('FizzBuzz' if i % 3 == 0 and i % 5 == 0 else 'Fizz' if i % 3 == 0 else 'Buzz' if i % 5 == 0 else i for i in range(1, 100 + 1)))👍15
А вот вам xyz оператор моржовый
Морж появился в Python относительно недавно. И многим он совсем не зашёл, в т.ч. и мне. 😏
Решил дать ему второй шанс. И морж практически провалил его. Но... 🦭
Единственная ситуация, где пара := оказалась удобной в использовании - замена бесконечного цикла while True и логической проверки выхода через break.
Было:
Стало:
А в качестве бонуса держите игру в камень, ножницы, бумага против компьютера с моржовым оператором и секретной фишкой внутри 😉
P.S. Про "секретную фишку" ровно через сутки на этом же месте. 🤫
:= 😱Морж появился в Python относительно недавно. И многим он совсем не зашёл, в т.ч. и мне. 😏
Решил дать ему второй шанс. И морж практически провалил его. Но... 🦭
Единственная ситуация, где пара := оказалась удобной в использовании - замена бесконечного цикла while True и логической проверки выхода через break.
Было:
while True:
res = input()
if res == EXIT:
break
...
Стало:
while (res := input()) != EXIT:
...
А в качестве бонуса держите игру в камень, ножницы, бумага против компьютера с моржовым оператором и секретной фишкой внутри 😉
from random import choice
DATA = ('победа', 'поражение', 'ничья',)
CHOICE = {'камень': 'камень', 'ножницы': 'ножницы', 'бумага': 'бумага', 'к': 'камень', 'н': 'ножницы', 'б': 'бумага', 'k': 'камень', 'n': 'ножницы', 'b': 'бумага', 'rock': 'камень', 'scissors': 'ножницы', 'paper': 'бумага', 'r': 'камень', 's': 'ножницы', 'p': 'бумага',}
print(f'Введи полный или короткий вариант из списка: {", ".join(key for key in CHOICE)}')
while (res := input('Что выбрал? ').lower()) in CHOICE:
print(f'Результат игры для выбора "{CHOICE[res]}": <<<{choice(DATA)}>>>')
else:
print('Exit game')
P.S. Про "секретную фишку" ровно через сутки на этом же месте. 🤫
👍8🔥1
Итак, в чём секрет игры в камень, ножницы, бумага. Точнее не самой игры, а её реализации.
Начнём с теории вероятностей. 2 игрока выбрасывают 1 из 3 возможных вариантов. Получаем девять различных комбинаций:
К-К - ничья
К-Н - победа
К-Б - поражение
Н-К - поражение
Н-Н - ничья
Н-Б - победа
Б-К - победа
Б-Н - поражение
Б-Б - ничья
Из них три выигрышных, три проигрышных и три с ничейным исходом. Итого 33,3(3)% или ⅓ для каждого из трёх возможных итогов.
А теперь внимание на следующие три строчки кода:
1. Импортируем функцию choice для выбора случайного элемента последовательности.
2. Формируем кортеж с результирующими вариантами. Их ровно три.
3. Выбираем случайным образом 1 из 3 вариантов, т.е. с вероятностью 33,3(3)% или ⅓.
Итого игра сохраняет вероятность 1 к 3, но полностью игнорирует выбор игрока. Всё по честному. Случайность, а не вы определяет победителя. 🤷♂️😅
Начнём с теории вероятностей. 2 игрока выбрасывают 1 из 3 возможных вариантов. Получаем девять различных комбинаций:
К-К - ничья
К-Н - победа
К-Б - поражение
Н-К - поражение
Н-Н - ничья
Н-Б - победа
Б-К - победа
Б-Н - поражение
Б-Б - ничья
Из них три выигрышных, три проигрышных и три с ничейным исходом. Итого 33,3(3)% или ⅓ для каждого из трёх возможных итогов.
А теперь внимание на следующие три строчки кода:
from random import choice
DATA = ('победа', 'поражение', 'ничья',)
choice(DATA)
1. Импортируем функцию choice для выбора случайного элемента последовательности.
2. Формируем кортеж с результирующими вариантами. Их ровно три.
3. Выбираем случайным образом 1 из 3 вариантов, т.е. с вероятностью 33,3(3)% или ⅓.
Итого игра сохраняет вероятность 1 к 3, но полностью игнорирует выбор игрока. Всё по честному. Случайность, а не вы определяет победителя. 🤷♂️😅
👍3🎉3😁2
День знаний закончился. Решил научить вас плохому 🤓
Блокбастер "Как написать поиск чисел Фибоначчи в пару строк" или завали себя на собеседовании сам. 😈
Код отлично работает. Поставленная задача решена. Просто и компактно. Но...
Предлагаю накидать список недочётов в комментарии. А завтра подведу итог отдельным постом.
Вперёд к знаниям 😉
Блокбастер "Как написать поиск чисел Фибоначчи в пару строк" или завали себя на собеседовании сам. 😈
fn, f1, f2 = int(input("До какого числа искать Фибоначчи? ")), 0, 1
for f in range(fn): print(f'{f} = {f1}'); f1, f2 = f2, f1 + f2Код отлично работает. Поставленная задача решена. Просто и компактно. Но...
Предлагаю накидать список недочётов в комментарии. А завтра подведу итог отдельным постом.
Вперёд к знаниям 😉
🔥1🤔1
Продолжение вчерашнего поста о том, как завалить собеседование. Идём по пунктам:
• Имена переменных на f - не лучшая идея. Начинает пестрит в глазах. При чём у всей команды 🤪
• Смешать инициализацию переменных начальными числами Фибоначчи и пользовательский ввод - фу, так не делают. Почему? См. следующий пункт.
• Ввод пользователя не проходит никаких проверок. Ужас 😱 Стоит ввести "плохой текст" и вылетаем с ошибкой. Да и не натуральные числа стоит фильтровать.
• Финальный гвоздь в крышку гроба - точка с запятой ради записи цикла в одну строку. Опытные Python разработчики не будут использовать ; где попало. Скорее всего вообще не будут использовать. 🚫
Такой вариант решения подошёл бы куда лучше. И даже сюда можно добавить def и name main для универсальности:
P.S. Наличие точки с запятой в коде подразумевает вопрос о других ЯП, где подобный стиль обязателен. И серию вопросов по ним. Хорошо, если в команду устраивается специалист с богатым опытом разработки. В противном случае весело смотреть как он самосливается по всемфронтам языкам.
• Имена переменных на f - не лучшая идея. Начинает пестрит в глазах. При чём у всей команды 🤪
• Смешать инициализацию переменных начальными числами Фибоначчи и пользовательский ввод - фу, так не делают. Почему? См. следующий пункт.
• Ввод пользователя не проходит никаких проверок. Ужас 😱 Стоит ввести "плохой текст" и вылетаем с ошибкой. Да и не натуральные числа стоит фильтровать.
• Финальный гвоздь в крышку гроба - точка с запятой ради записи цикла в одну строку. Опытные Python разработчики не будут использовать ; где попало. Скорее всего вообще не будут использовать. 🚫
Такой вариант решения подошёл бы куда лучше. И даже сюда можно добавить def и name main для универсальности:
while True:
try:
limit = int(input("До какого числа искать Фибоначчи? "))
except ValueError:
print("Нужно натуральное число, а не текст!")
continue
if limit < 1:
print("Нужно число от одного и выше!")
else:
break
f1, f2 = 0, 1
for i in range(limit):
print(f'{i} = {f1}')
f1, f2 = f2, f1 + f2
P.S. Наличие точки с запятой в коде подразумевает вопрос о других ЯП, где подобный стиль обязателен. И серию вопросов по ним. Хорошо, если в команду устраивается специалист с богатым опытом разработки. В противном случае весело смотреть как он самосливается по всем
👍7
Все знают, что
Offtop mode on
Если нет, дайте знать, расскажу в следующем посте.
Offtop mode off
А ещё каждому известно, что Python дружелюбен и готов простить строку import в середине кода.
Но есть страшная тайна о манипуляциях со временем, и путешествием в будущее, которое нельзя отложить на потом. 🤫
Да, вы верно догадались. Речь об импорте будущего. А если быть точным о:
Получим:
Как ни крути, а импортировать будущее можно лишь в начале пути.
И да, вопрос об использовании в Python точки с запятой вызывает споры среди неокрепших умов джуниоров и тех, кто привык к ним в Си-подобных языках.
Но что точно неоспоримо, так это отказ от фигурных скобок. Даже в далёком будущем и с импортом в начале файла:
нет и шанса на работу с фигурными скобками:
🤓
import принято писать в начале файла. И обычно все знают об особенностях сортировки импортов. Offtop mode on
Если нет, дайте знать, расскажу в следующем посте.
Offtop mode off
А ещё каждому известно, что Python дружелюбен и готов простить строку import в середине кода.
Но есть страшная тайна о манипуляциях со временем, и путешествием в будущее, которое нельзя отложить на потом. 🤫
Да, вы верно догадались. Речь об импорте будущего. А если быть точным о:
from __future__ import ...Получим:
SyntaxError: from __future__ imports must occur at the beginning of the fileКак ни крути, а импортировать будущее можно лишь в начале пути.
И да, вопрос об использовании в Python точки с запятой вызывает споры среди неокрепших умов джуниоров и тех, кто привык к ним в Си-подобных языках.
Но что точно неоспоримо, так это отказ от фигурных скобок. Даже в далёком будущем и с импортом в начале файла:
from __future__ import bracesнет и шанса на работу с фигурными скобками:
SyntaxError: not a chance🤓
👏7🤔2