KISS — «Keep it simple, stupid» — «Делай проще, тупица»! Очень важный принцип. И с одной стороны, кажется, кто же будет усложнять себе жизнь? На практике многие новички, да и программисты-профессионалы этим страдают
Почему программисты усложняют?
Новички часто просто не разбираются в вопросе и у них свой, дилетантский взгляд на то, что просто а что сложно. Например, для кого-то очень сложно поначалу использовать методы строк и массивов/списков в языках вроде Python или JavaScript. Многие простые и удобные инструменты в программировании кажутся, пока их не понял, очень сложными.
Так же любой программист может быть фанатом какой-то концепции или какого-то набора и тащить его в любой проект и пытаться максимально использовать. Новички при этом, как и во многих других профессиях, часто считают, что профессионалы используют сложные и навороченные способы разрешить проблему или выполнить поставленную задачу. А это не так. Профессионал любит экономить своё время. Поэтому если можно решить задачу простым путём, то профессионал решит её простым путём.
Что такое SOLID, KISS, DRY и YAGNI?
Очень нужная вещь во многих направлениях — объекты, классы, и шаблоны проектирования (как эти объекты и классы использовать). Код одной и той же программы с помощью них можно сделать как очень простым понятным, так и огромным и перегруженным.
Как следовать принципу KISS?
Используйте декомпозицию — разделяйте сложные элементы на более простые составляющие. Кстати, принцип DRY тоже несколько про это.
Вам нужны пара функций из огромной библиотеки? Не стоит подключать её всю целиком для этого. Можно найти библиотеку поменьше. В Python можно импортировать из библиотеки только то, что вам реально нужно.
Объекты и классы — не переусердствуйте с ними, уровень абстракции можно увеличивать бесконечно, но зачем?
Абсолютная точность, детализация, чёткость и вылизанность в проекте нужны не всегда. Не все же программируют медицинское оборудование, например, или самолёты? Делайте только в нужном объёме.
Не добавляйте в проект что-то на всякий случай. Даже если вы программируете что-то для атомной электростанции, вам скорее всего дадут информацию о том, что нужно а что нет. А так вы только увеличите сложность проекта и вероятность ошибиться.
Пара историй не из программирования
Для иллюстрации принципа совсем новичкам расскажу историю и притчу.
Еще раз о KISS и трендах
Последние несколько лет async вообще и asyncio в частности в питоне все больше набирают популярность и их все чаще используют. При этом иногда забывают о принципе KISS (Keep it simple, stupid) и о том, какие вообще проблемы решает асинхронный код и зачем он нужен. В этой статье я бы хотел описать пример, когда задачу можно и, на мой взгляд, нужно решать без использования async. И вообще, практически без всего.
Для начала подключим к компьютеру (ноутбуку) одну вэб-камеру. Далее нам нужно с этой камеры раз в 10 секунд запрашивать кадр и сохранять его. Для простоты примера будем сохранять кадр на диск. Эта задача простая и решение тоже будет простым, даже примитивным я бы сказал.
Kissing device lets you smooch over the internet
import time import cv2 def main(): source = 0 frame_file_path = ‘.jpg’ cap = cv2.VideoCapture(source) while True: ret, frame = cap.read() if not ret: print(‘Failed to get a frame’) break cv2.imwrite(frame_file_path, frame) time.sleep(10) cap.release() if __name__ == ‘__main__’: main()
Чем хорош данный скрипт? Тем, что он прост, понятен и надежен как лом и не требует никаких внешних инструментов типа cron-а.
Теперь немного масштабируем наш пример: добавим еще одну камеру и скажем, что с нее нам нужны кадры каждые 15 секунд. Если на проекте вы активно пользуетесь asyncio, то можете по инерции поступить следующим образом: сказать, что раз задача по существу I/O Bound, а камер стало больше, то это работа для asyncio. Затем взять какой-нибудь планировщик задач типа APScheduler, который поддерживает asyncio и с его помощью и помощью лома накидать что-то вроде такого.
import asyncio from functools import partial import cv2 from apscheduler.schedulers.asyncio import AsyncIOScheduler async def job(source, target_file_path): cap = cv2.VideoCapture(source) ret, frame = await asyncio.get_event_loop().run_in_executor(None, partial(cap.read, cap)) if not ret: print(‘Failed to get a frame’) return await asyncio.get_event_loop().run_in_executor(None, partial(cv2.imwrite, target_file_path, frame)) def main(): frame_0_file_path = » frame_1_file_path = » scheduler = AsyncIOScheduler() scheduler.add_job(job, ‘interval’, seconds=10, kwargs=) scheduler.add_job(job, ‘interval’, seconds=15, kwargs=) scheduler.start() try: asyncio.get_event_loop().run_forever() except (KeyboardInterrupt, SystemExit): pass if __name__ == ‘__main__’: main()
На первый взгляд все неплохо, но это на первый взгляд.
Помимо дополнительной внешней зависимости мы собрали под капотом корутины, asyncio с ивент лупом и потоки для запуска синхронных функций асинхронным образом. И теперь вместо топорной и надежной программки у нас есть целый технический букет, с которым можно повозиться и от этого кайфануть. Но оно нам надо?
Мне вот как инженеру не очень 🙂 Если вспомнить, что async, ивент луп и вот это все призваны при написании I/O Bound приложений экономить ресурсы при большой нагрузке, а нагрузки у нас нет, да и камер будет конечное и вполне осмысливаемое число, то могут закрасться смутные сомнения. А нужен ли нам там asyncio тут вообще?
И можно прийти к выводу, что не нужен и что вместо запуска асинхронных задач на ивент лупе, можно воспользоваться классом apscheduler.executors.pool.ProcessPoolExecutor, который позволит нам запускать наши джобы в процессах. Есть еще класс, который позволяет нам запускать джобы в потоках. Но сомнения у нас смутные, поэтому мы его тоже отбросим. Получится что-то вроде такого:
import cv2 from apscheduler.schedulers.blocking import BlockingScheduler def job(source, target_file_path): cap = cv2.VideoCapture(source) ret, frame = cap.read() if not ret: print(‘Failed to get a frame’) return cv2.imwrite(target_file_path, frame) def main(): frame_0_file_path = » frame_1_file_path = » scheduler = BlockingScheduler( < ‘apscheduler.executors.default’: < ‘class’: ‘apscheduler.executors.pool:ProcessPoolExecutor’, ‘max_workers’: 2 >>) scheduler.add_job(job, ‘interval’, seconds=10, kwargs=) scheduler.add_job(job, ‘interval’, seconds=15, kwargs=) scheduler.start() if __name__ == ‘__main__’: main()
Так намного лучше: нет потоков, нет asyncio с ивент лупом не по делу.
Но все еще не идеал, ибо есть APScheduler с какими-то внутренним механизмами. Оно нам надо? Мне — нет. Наше решение для одной камеры было максимально простым, тупым, надежным и имело всего одну зависимость от которой, увы, не убежишь. Почему бы нам тогда не вспомнить про принцип KISS еще разок и не взять первую версию программы, не параметризовать ее и не запускать ее для каждой камеры? Этот подход мне лично нравится больше всего: минимум усилий (если подумать о нем сразу), максимум надежности (я как инженер люблю все надежное) и максимально просто сопровождение, а точнее его отсутствие 🙂
В итоге получаем следующее:
import argparse import time import cv2 def main(source: int, frame_file_path: str, interval: int): cap = cv2.VideoCapture(source) while True: ret, frame = cap.read() if not ret: print(‘Failed to get a frame’) break cv2.imwrite(frame_file_path, frame) time.sleep(interval) cap.release() if __name__ == ‘__main__’: parser = argparse.ArgumentParser() parser.add_argument(‘—source’, type=int) parser.add_argument(‘—target-frame-path’, type=str, dest=’target_frame_path’) parser.add_argument(‘—interval’, type=int) args = parser.parse_args() main(args.source, args.target_frame_path, args.interval)
Такое же простое, надежное и понятное решение как лом. А против лома, как известно, приема нет 🙂
Источник: habr.com
KiSS
На нашем сайте находятся списки программ, которые помогают в конверсии и в ежедневной работе с расширениями файлов. Одной из них является также программа KiSS. С помощью следующих сопоставлений Вы можете подробно ознакомится с возможностями программы. Вы узнаете, какие расширения файлов программа может обслуживать.
Расширения, обслуживаемые KiSS
KiSS — дополнительная информация
Программа KiSS может использоваться также для конверсии файлов между разными форматами. Если это так — в сопоставлении Вы найдете информацию об этих расширениях. Благодаря использованию программ, таких как KiSS и похожих, конверсия и изменение расширения файлов не должны представлять проблем, а прочтение указанного содержания, закодированного в файле, будет отчетливым, понятным, совместимым с оригиналом. Все программы (#PRGORAM# также) рекомендуем скачивать непосредственно со страницы производителей
Источник: www.extension.info