• Почему большинство программистов выбирают Mac?

    @DAlex
    Занимался разработкой из линукс несколько лет - устраивало все. На новом месте работы выдали мак... Было мучительно первые несколько недель. Потом смирился... Всё-таки линукс более гибким мне представляется (работал в ОС семейства дебиан). Я занимаюсь бэкендом большую часть времени на Питоне, немного фронта... Ничего такого, чего не было бы в линукс в маке я не нашёл. А вот некоторые вещи (модули, сторонние приложения) в линукс ставятся проще.
    Дома все ещё линукс - мечты купить мак нет.
    Также от многих слышал, что на маках сидят дизайнеры и мультимедийщики.
    Ответ написан
    Комментировать
  • Как ускорить скриншоты python?

    @AquaDll Автор вопроса
    ru
    Забыл закрыть. WinApi очень сильно помог. С 15fps к 60+
    Ответ написан
    Комментировать
  • Что тут учить в библиотеке aiogram?

    Vindicar
    @Vindicar
    RTFM!
    1. Читаешь Quick Start и примеры кода.
    2. Ищешь пример кода, который наиболее походит на нужную тебе функциональность.
    3. Наткнувшись на непонятное, ищешь нужный раздел документации и читаешь до наступления просветления.
    4. Повторять 2-3, пока нужный пример кода не будет полностью понятен.
    Я так делаю, во всяком случае.
    Ответ написан
    1 комментарий
  • Можете оценить код python?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Общепринятый ключ в такого рода утилитах для рекурсивной обработки подкаталогов -r/--recursive. Ваш вариант интуитивно не очень понятный.
    Сразу хочется придраться к наименованию основной функции и переменных. view_folder - подразумевает по смыслу некое неизменяющее воздействие, просмотр или что-то эдакое, но не то, что по факту делает её код. process_folder или clean_unpaired_raws подощло бы больше. А если добавить докстринг и тайпхинтинг для параметров, было бы вообще замечательно.
    И да, параметры следует тоже называть консистентно. У вас одно и то же называется в программе сильно по-разному. Зачем вносить неразбериху? Зачем экономить несколько символов в ущерб понятности и читабельности?
    Параметры следовало бы передавать по имени. Из-за неочевидного и неконсистентного именования приходится каждый раз смотреть что туда передаётся, причем внимательно следить, отсчитывая параметры позиционно и читать что про соответствующий параметр пишется в описании аргпарсера. Код должен быть максимально прозрачным даже для дго, кто первый раз его видит.

    Если уж вы запросили ревью, то буду цепляться по порядку без учета степени и значительности недочетов. Какие-то вещи вполне норм, но я бы сделал иначе, их тоже буду упоминать.
    Например, я бы в main передавал вектор аргументов с умолчанием в виде None. При передаче None доставал бы вектор из sys.argv[1:], как это делает парсер аргументов внутри, а при передаче конкретного вектора, использовал бы его. Это помогло бы протестировать парсинг параметров, если до таких автотестов дошли бы руки.

    То, что у вас в основной функции, принято называть спагетти-кодом. Следует разделять код на удобные для понимания и тестирования части.

    Я бы вынес в отдельную функцию формирование итератора по файлам.
    Отдельной безопасной функцией генерил бы дифф.
    Отдельно бы этот дифф применял. Отдельно (и опционально) спрашивал бы подтверждения пользователя.
    Часто от утилиты требуется "тихая" работа или работа без лишних вопросов к пользователю. Для этого даже применяются специальные ключи, вроде -y/--yes.

    Почему бы не импортнуть from pathlib import path вместо постоянного обращения pathlib.Path? Где-то экономите букву, а где-то вот так вот...

    Вот это условие:
    pathlib.Path(str(file.parent/file.stem) + img).is_file()

    Следовало бы записать так:
    file.with_suffix(img).exists()
    Это короче и правильнее. Есть нюанс. У вас с таким именем может быть не только файл, но и каталог. Об этом часто забывают. Я бы в таких неоднозначных ситуациях следовал более безопасному поведению, например сохранению рав-файла, если соответствующая картинка - не картинка, а вообще каталог.
    if 'raw_file' in str(file): #Если файл ранне был перемещен в папку raw_file его не игнорируем
        continue

    Игнорируете файлы в каталоге, заданном "магической константой". А если у пользователя такие каталоги используются для других целей?
    В идеале нужно хотя бы задекларировать такое поведение на уровне документации.
    Я бы ввёл перечень подкаталогов, которые игнорируются при сканировании. Позволил бы указывать название каталога, куда скидывать равы, в параметрах утилиты, добавлял бы это имя в список игнорируемых пол умолчанию каталогов.
    Позволил бы список игнорируемых каталогов изменять.

    Вы проверяете принадлежность фала подкаталогу проверкой вхождениея подстроки в его полное имя, но это неправильно, ведь такой кусок строки может быть в составе другого каталога или файла.
    Например в полном пути каталога, который нужно почистить будетет что-то вроде такого:
    "/home/dave/please_clean_raw_files_here/vacations2020/my_camera/IMG1010.RAW"
    Все равы в "/home/dave/please_clean_raw_files_here/vacations2020/my_camera/" будут проигнорированы.
    Неожиданно, правда?

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

    Часто у рав-файла и JPG одна и та же дата-время в свойствах файла или в exif. Это позволит навярняка удалять только гарантированно непарные файлы, и вы не зацепите случаи, когда у камеры сбросился или провернулся счетчик кадров. Также решится проблема с ситуацией, когда в одном каталоге есть фотосеты с разных камер, которыые именуют фотки аналогичным образом. Очень трудно совпасть по времени кадра до долей секунд.

    Вот в таких сучаях следует не следует инвертировать условие и углублять код, превращая его в спагетти:
    if not len(difference) == 0:
        folder = str()
        print('\nRaw without jpg:')
        for file in difference:
            if not folder == file.parent:
                folder = file.parent
                print(f'\nFolder: {folder}')
            print(f'- {file.name}')
    else:
        sys.exit(f'\nThere are no suitable files in the {path} folder\n')

    Смотрите, если по одной из веток происходит выход, то его нужно сделать сразу, чтобы не забивать голову лишними отступами и уровнями ветвления:
    if not difference:  # да в питоне так проверяют пустоту списка
            sys.exit(f'\nThere are no suitable files in the {path} folder\n')

    А ещё обратите внимание, что '\nRaw without jpg:' выведется даже если ключи заставляют утилиту удалить все равы, даже те, к которым есть парные картинки. То есть ваша тулза откровенно врёт пользователю в некоторых ситуациях.

    Вот здесь вы фактически группируете файлы по каталогам:
    for file in difference:
        if not folder == file.parent:
            folder = file.parent
             print(f'\nFolder: {folder}')
        print(f'- {file.name}')

    Отчего бы не вынести это в отдельную функцию, чтобы не захламлять код?
    Да, она использовалась бы лишь единожды, но будучи понятно названной и понятно задокументированной эта функция сделает ваш код гораздо прозрачнее. Её вызов будет нести понятные последствия, а из спагетти-кода главной функции уйдёт приличный кусок, он будет заменен одним вызовом.
    Обратите внимание на tertools.groupby. Она умеет группировать последовательность по результату лямбды и вы сможете сделать генератор генерторов, которые будут выдавать вам списки файлов по каталогам.

    Пчему бы не заменить все вот такие куски на отдельную функцию с булевским результатом?
    while True:
        confirm = input('\nMove this files to a folder "raw_files"? press: y/n: ')
    [...]

    Пусть мучает пользователя бесконечно, пусть сделает системный выход, если приспичит, а лучше вальнётся с исключением, чтобы можно было при ее применении освободить ресурсы по finally.
    Зато её вызов был бы простым и лаконичным:
    if confirm('\nMove this files to a folder "raw_files"? press: y/n: '):
        move_file(difference, difference_folder)
        sys.exit('Complete\n')


    Почему у вас функция move_file называется так, будто перемещает один файл, аргумент у нее наывается в единственном числе, а принимает она туа целый список путей?!!
    Это либо злонамеренность, либо халатность. Нельзя так относиться к коду. Вы его пишете и на ходу меняете не думая о названиях, не думая о документации, не думая о консистентности. Полагаю раньше эта функция отвечала за перемещение только одого файла, а потмо вы вспороли ей брюхо и заставили обрабатывать список, но не позаботились ни о правильном названии, ни об изоляции... Франкенштейн у вас получился.

    Дважды вычисляете одно и то же значение:
    if not pathlib.Path(file.parent / 'raw_files' / f'{p.stem}({i}){file.suffix}').is_file():
        pathlib.Path(file).replace(file.parent / 'raw_files' / f'{file.stem}({i}){file.suffix}')

    У вас тут и магическая константа в коде на каждом шагу, и неправильно импортированный pathlib... Cнова забыли, что помимо файлов бывают каталоги и каталог с определённым именем просто сломают логику вашей тулзы.
    Отсутствует корректная обработка ошибок. Открытый в каком-нибудь редакторе файл или папка с расширением .raw поломает к чертям всю работу и оставит её в некоторых случаях недоделанной, а это ещё хуже, чем вовсе не сделать ничего.

    Зачем вы каждый раз делаете приведение к Path?
    pathlib.Path(f / 'raw_files')
    Результат конкатенации с Path будет тоже Path. Нет смысла приводить тип? И так в куче мест по всему коду!

    Почему бы не сделать одну функцию по побработке одного единственного файла?
    def move_raw_file(file: Path, dest_folder: typing.Union[Path, str None]=None, exists='safe'):

    Переносит файл `file` в каталог dest_folder или удаляет, если он задан как None.
    dest_folder может быть задан абсолютно или относительно родительского каталога file.
    `exists`: safe, replace, ignore, error
    В общем всё плохо. Учиться и учиться. Но бывает и хуже. так что дерзайте.

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

    Нужно использовать исключения, причем так, чтобы код становился прозрачнее и было понятно что произойдёт в каких случаях.
    Нужно понимать как устроена файловая система и учитывать ее нюансы. Понимать, что файлы и папки - это немного разное, но они в едином пространстве имён. Понимать про абсолютные и относительные пути. Делать тулзы по умолчанию безопасными.
    Понимать, что файлы могут быть поименованы произвольно, а вашей тулзе могут дать пожевать корневой каталог. Надо, чтобы она не загадила винт подкаталогами и не перетащила равы куда не следует.
    Ответ написан
    5 комментариев
  • Не понимаю как решить ошибку в DeepFace?

    @PavelMos
    Почему бы с английского не перевести ошибку и не попробовать разобраться в ней ,
    gender = face_analyze(image).get('gender')
    при face_analyze(image) вероятно возвращается ошибка ValueError, а следующая часть конструкции .get(... пытается вызвать для нее функцию get('gender'), которая есть у нормального объекта, возвращаемого face_analyze(image), но нет у ошибки.
    Итого - face_analyze(image) в данном скрипте не работает. Почему - ищите в документации и в интернете.
    Это на первом же image происходит или в процессе перебора ?
    см. тут так же -
    https://github.com/serengil/deepface/issues/161
    Ответ написан
    2 комментария
  • Есть ли дейтвительно хороший GUI на Python?

    @kivicode
    Могу ещё посоветовать pyimgui (порт аналогичной либы с плюсов), весьма удобная вещь и выглядит неплохо
    Ответ написан
    Комментировать
  • Как нынче получать деньги от зарубежных работодателей?

    saintgeo23
    @saintgeo23
    Frontend-developer
    Да, р/с ИП, и нет проблем.

    Но я бы не стал так идеализировать Тинькофф.
    У меня и моих коллег сложилось о нем не лучшее (мягко сказано) впечатление.

    Кейс такой (все суммы, даты и курсы являются вымышленными, любое совпадение с реальными - случайность):
    - скажем, 1 января мне на транзитный счет приходит 1000 евро оплата по контракту. курс ЦБ на момент поступления средств - 100 рублей за евро.
    - банк автоматически должен продать 80% из этих 1000 евро, конвертировав их в рубли, и зачислить на мой рублевый счет.
    - внутренний курс покупки в тинькофф на этот момент - 95 рублей за евро. я отправляю документы на валютный контроль (далее - ВК), внутренне соглашаясь, что ок, пусть будет по 95, ждать не буду.
    - ВК длится 3-4 дня (к слову, раньше он был не больше 2 часов), за которые курс евро снижается и на момент окончания ВК составляет 75 рублей за евро.

    И тут как раз случается магия: оказывается, Тинькофф обменивает эти обязательные 80% валютной выручки по курсу на момент подтверждения операции ВК, а не на тот момент, когда я подтвердил операцию и отправил платеж на ВК. А в налоговую базу мне этот платеж придет по курсу, который действовал на момент поступления средств на транзитный счет - 100 рублей за евро.

    Советую обратить внимание на другие банки, где курс обмена обязательной части выручки берется на момент подтверждения вами платежа, а не момент подтверждения его ВК. Да, там изначально разница в курсе обмена от Тинькофф может быть в пределах 1 рубля в меньшую сторону, но для меня это лучше, чем 3-4 дня сидеть и буквально молиться, только бы курс евро не рухнул ниже плинтуса.
    Ответ написан
    1 комментарий
  • Есть код питон. Как исправить?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Для начала отложить ботописательство и изучить python.
    Например, по книге Марк Лутц - Изучаем python. 5-e издание.
    Без знания основ вы, каждый раз как будет выскакивать ошибка, будете бежать в гугл/сюда/на stackowerflow с подобными вопросами.
    Конкретно по вашему вопросу - в указанной книге пятый раздел первого тома полностью посвящен модулям, на отсутствие которого ругается интерпритатор.
    Ответ написан
    Комментировать
  • Как нынче получать деньги от зарубежных работодателей?

    firedragon
    @firedragon
    Не джун-мидл-сеньор, а трус-балбес-бывалый.
    payoner + tinkoff
    Ответ написан
    Комментировать
  • Как нынче получать деньги от зарубежных работодателей?

    @Stalinko Куратор тега Фриланс
    PHP'шник и фрилансер до мозга костей
    SWIFT и крипта.
    Ответ написан
    Комментировать
  • Как в python увидеть текст диалогового окна сторонней программы?

    Vindicar
    @Vindicar
    RTFM!
    Смотря чем ты автоматизируешь. pywinauto позволяет обращаться к диалоговым окнам, тогда тебе потребуется только найти внутри текст - скорее всего, это будет контрол типа "Static".
    Ответ написан
    1 комментарий
  • Какую лучше выбрать wifi камеру для системы распознавания лиц?

    @mordo445
    Скажите пожалуйста, какой алгоритм используете, какие у него ограничения? Второе, у вас какое то конкретное решение (например учитывать в конкретном магазине, в конкретной точке уникальных посетителей) или вам нужна лабораторная установка? Лучшие показатели FRR/FAR я получал от коробочных программных решений, с камерами, имеющими матрицу 2 MPix, и способных выдавать 60 fps. Используется при этом кадровая скорость не полная (6-8 fps), просто качество матрицы и процессора (или SoC) у таких камер повыше. От применения будет зависеть выбор объектива. Высокие показатели можно получить на объективах без дисторсии, но это 1. не про wi-fi камеры 2. Обычно дороже 100$.
    Если же рекомендовать в слепую, по вашим условиям, то вам должны (с ограничениями) подойти:
    1. Hikvision DS-2CD2425FWD-IW -- около 60$, набор объективов таков, что уверенное распознавание возможно в упор, метров с трех. Дисторсия присутствует.
    2. Dahua DH-IPC-K35AP -- то же самое по условиям применения и цене что и предыдущий вариант, но на проце ambarella
    3. Dahua DH-IPC-K22P -- почти то же, но уже от 45$, картинка чуток похуже
    Камеры от щяоми и им подобные не могу рекомендовать -- намучаетесь с получением потока. Не wi-fi сетевые камеры дешевле при прочих равных. Камеры от ez-wiz, imou, hiwatch серьезно ниже по качеству картинки, чем то, на что бренд не стесняется клеить логотип, за редким исключением.
    Ответ написан
    5 комментариев
  • Как обрабатывать на бэкенде случайные множественные запросы с фронтенда?

    @rPman
    К сожалению правильно реализовать это можно, только имея доступ к исправлению фронтэнда
    Исключение дублированных данных можно реализовать добавлением поля - идентификатор запроса на фронтэнде, добавляемый в момент отправки данных, значение его же генерируется в момент открытия формы на клиенте (кстати тут нужно хорошо думать, когда именно должен появляться новый идентификатор запроса).

    Если же фронтэнд трогать нельзя, значит бакэнд должен как то идентифицировать дубляж данных. Самое простое (если это позволяет бизнеслогика) - хранить в сессии хеш (точнее список таковых за последние несколько секунд) последнего запроса на изменение данных с фронтэнда и игнорировать те, у которых он повторяется. Почему нужно хранить список, потому при использовании ajax и проблемах с интернет, запрос может заметно подзадержаться, пользователь может перейти на другую страницу (SPA или использование web worker) отправить там запрос и перейти снова к первоначальной, и отправить повторно.
    Ответ написан
    Комментировать
  • Как обрабатывать на бэкенде случайные множественные запросы с фронтенда?

    vabka
    @vabka
    Токсичный шарпист
    Если трогать фронт нельзя, то как единственный возможный вариант - на все последующие запросы кидать ошибку, либо делать лимит запросов.

    Если фронт трогать можно, то есть разные варианты:
    https://habr.com/ru/company/yandex/blog/442762/
    Ответ написан
    Комментировать
  • Алгоритм табуляции из python?

    GavriKos
    @GavriKos
    Питон тоже можно поломать если смешать табы и пробелы.
    Ответ написан
    Комментировать
  • Как профилировать асинхронный код?

    Нагуглил Yappi.
    Ответ написан
    Комментировать
  • Функции по "Чистому коду" - нужно ли это?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Читайте дальше. В книге доходчиво описывается, что все парадигмы и практики в программировании направлены на управление сложностью изменений. Вы не можете знать, как ваш код должен будет измениться завтра, но точно то, что маленькие функции будет легче перекомпоновать. Естественно, всё это имеет смысл, если у вас что-то сложнее hello world'а.
    Ответ написан
    2 комментария
  • Существуют ли профайлеры с построением карты для python?

    ayazer
    @ayazer
    Sr. Software Engineer
    да. по сути вам нужен профайлер + визуализатор к нему. например cprofile + kcachegrind
    вот тут есть пара полезных ссылок, можно начать с них
    Ответ написан
    4 комментария
  • Какие игровые движки существуют для Python?

    @WorldEn
    На данный момент для Python есть следующие движки на выбор:

    2D:
    - Cocos 2D (сам лично им не пользовался и ничего сказать не могу, но знаю, что русскоязычное сообщество использует этот движок для с++, вместо python)

    - Kivy (это потомок Pygame, о котором напишу ниже. В основном он предназначен для создания приложений под андроид, но 2D игры тоже на нём делают)

    - Собственно PyGame (Это библиотека Python для создания 2D игр. Очень проста в освоении и есть много уроков и книг на английском и русском. Можно создать практически любую 2D игру. Русское сообщество тоже есть. Хорошая книга на русском здесь)

    - Так же есть 2D + 3D движок с внутренним языком программирования, который очень похож на Python. Т.е если знаешь Python, то этот ЯП освоишь максимум за неделю или даже меньше. Godot Engine

    3D:
    - Из 3D движков единственные это Blender Game Engine. Движок прост в освоении и, в принципе, даже не надо знать языка программирования для создания хорошей игры. Однако если знаешь Python, то это большой плюс, так как скрипты для этого движка пишутся именно на этом языке. Хорошая книжка по движку здесь, а здесь перевод. Примеры игр: раз, два.

    - И , конечно же, Panda 3D. Это не конструктор игр, как Blender Game Engine, где ты создаешь игру, не написав строчки кода. Это конкретный игровой движок, где ты с нуля пишешь код на Python используя API этого движка и создаешь 3D игру. Я сейчас сам его осваиваю и у движка есть живое русскоязычное сообщество, где могут подсказать если что. Так же по движку много видео уроков и книг на английском. Вот одна из этих книг- она на английском, но написано всё понятно, что даже я, не зная инглиш, понимаю))))) Примеры игр: раз, два, три.
    Ответ написан
    9 комментариев
  • Ресурс для изучения паттернов проектирования на Python?

    un1t
    @un1t
    Марк Саммерфилд "Python на практике"
    Ответ написан
    Комментировать