• Как сделать, чтобы при записи в csv файл числа были числовыми, а не датами?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Вы самое главное упустили. В виде дат эти строки выглядят в экселе, а CSV тут ни при чем. Это простой текстовый формат и в нем нельзя указать тип данных ячейки.
    Вам в соседнем ответе уже порекомендовали настроить тип данных ячеек в экселе. Это именно его, экселевская, проблема. Слишком "умный".

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

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

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Нифига. Никак тут не продолжить снаружи. Итальянец писал код - не иначе. Спагетти явно с сыром.
    Но у вас есть возможность форкнуть и отрефакторить этот парсер, хотя лучше бы взяли просто другой хороший, пусть не из стандартной библиотеки.

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

    О, ну и ещё одна идея на грани фола. Попробуйте _strict перекрыть свойством, а на геттер инициировать ворнинг. Правда вы так не узнаете на каком именно дубле проблема. А ещё, чтобы не путаться на случай нерелевантных обращений _strinct, можно включать режим ворнингов и выключать до и после перекрытого метода. Такой себе грязный хак основанный на побочных эффектах.

    Можно пофиксить _strict параметр и ошибка не будет инициироваться, но вы останетесь без ворнинга.
    Ответ написан
    5 комментариев
  • Почему python не видит модуль хотя __init__.py есть?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Питон просто не знает, что каталоге server (а для test1.py это "..") можно искать модули и пакеты.
    Сделайте так:
    sys.path.append('..') в test1.py и в нём можно будет импортировать ваш пакет, если запускаете вы прямо его (test1.py)

    Питон при импорте ищет модули по путям, перечисленным в sys.path.
    Один из вариантов решения этой проблемы для вас - это сделать норальный setup.py, а потом установить его в редактируемом режиме (pip install -e .).
    Так папка, где лежит пакет, будет добавлена в sys.path и он будет импортироваться откуда угодно.
    Ответ написан
    Комментировать
  • Как сделать, чтобы при выводе в консоль новой строки, она моментально записывалась в csv?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Это можно (и правильнее) делать снаружи:
    ./my_script.py | tee the.csv
    Так вы получите весь выхлоп и в терминал и в файл.

    Но можно и по-другому. например сделать свой кастомный print:
    with open('the.csv', 'w') as f:
        def my_print(s):
            print(s)
            print(s, file=f)
            f.flush()
        
        for i in range(1000):
            my_print(i)
            time.sleep(12)

    Можно сделать свой класс, поддерживающий протокол записи (write) и в конструктор получающий набор потоков ввода/вывода, в которые будет писать.
    class IOFork:
        def __init__(self, *streams, flush=True):
            self.streams = streams
            self._flush = flush
    
        def write(self, s: str):
            for stream in self.streams:
                stream.write(s)
                if self._flush:
                    stream.flush()
    # ...
    import sys 
    import time 
    with open('the.csv', 'w') as f:
         io = IOFork(f, sys.stderr) 
         for i in range(100): 
             print(i, file=io) 
             time.sleep(1)

    Вы можете убедиться, что всё пишется вовремя, если в соседнем терминале будете подслушивать выходной файл:
    tail -F the.csv
    Ответ написан
  • Как игнорировать пользователя?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    По приходу сообщения проверяйте не замучен ли пользователь. Если-таки да, то пусть бот не обращает на него внимания.
    Или в чем вопрос? Вы его как-то невнятно описали.
    Ответ написан
  • Как лучше посчитать записи в базе?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    SELECT type, count(*)
    FROM table_name
    GROUP BY type
    Ответ написан
    3 комментария
  • Как реализовать копирование файлов с одинаковыми именами под разными именами, а не перезаписывать созданный файл при нахождении одноимённого файла?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Есть несколько простых правил:

    0. Следите за отступами и форматируйте код правильно.
    Для питона это самое главное правило. Вы некорректно наставили тегов для оборачивания кода, я вам лишние убрал, но ваши отступы в коде поломаны. К этому нужно относиться внимательно.
    Помните, что помимо пробелов бывают табуляции. Табуляция - это один широкий символ, но его ширина нигде не регламентирована, а питон по количеству пустых символов вначале строки понимает её вложенность в коде. Само собой смешение табуляций и пробелов в питоновском коде ведёт к страшной неразберихе и гарантированным ошибкам. Холивару "пробелы против табов" не одна сотня человеко-лет, но есть общее правило, зафиксированное в PEP: используйте 4 пробела в качестве одного отступа. Всегда. Без исключений.

    1. Не используйте скобки там, где они не нужны:
    disk = ('C:\\')
    filen1 = (f'{root}' + str('\\') + f'{name}')

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

    1. Не конкатенируйте пути вручную, как вы это делаете здесь:
    f'{root}' + str('\\') + f'{name}'
    Приведение строки к строке бессмысленно. Могли бы просто написать так: f'{root}\\{name}', но и это плохая идея, потому что нельзя конкатенировать пути вручную. В разных операционных системах используются разные символы-разделители в путях. В питоне для работы с путями есть модули: os.path (древний как навоз мамонта) и pathlib (новый, объектный, очень удобный).

    2. Используйте pathlib для работы с путями.
    Изучите эту библиотеку. Вы откроете для себя массу полезных вещей.

    3. Используйте оператор with при работе с закрываемыми ресурсами.
    Ваш код:
    file1 = open(filen1, 'rb')
    file2 = open(filen2, 'wb')
    file2.write(file1.read())
    file1.close()
    file2.close()

    Станет таким:
    with open(filen1, 'rb') as file1, open(filen2, 'wb') as file2:
        file2.write(file1.read())

    А с использованием pathlib ещё лаконичнее:
    directory = Path('path/to/my/dir')
    fn1 = directory / 'file1.jpg'
    fn2 = directory / 'file2.jpg'
    file2.write_bytes(file1.read_bytes())

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

    4. Не смешивайте работу с каталогами и с файлами:
    if name in dirs or name in files:
    В каких-то случаях, возможно, и есть сходства, ведь в файловой системе каталог - это тоже файл. Но вы не сможете его ни прочитать, как таковой ни записать. По логике вашей программы получается, что, если есть каталог с таким именем и расширением, то вы его будете тоже пытаться читать. на этом ваш код и упадёт.
    В pathlib, кстати, есть отличный метод rglob, который рекурсивно итерируется по всем путям, соответствующим маске. Сделать это можно относительно любого каталога:
    files = Path('c:').rglob('*.jpg')
    найдёт все jpeg-картинки на вашем диске c:.
    При этом вы получите объект, по которому можно итерироваться циклом или превратить его в список. Элементы такой последовательности будут тоже типа pathlib.Path.

    5. Для решения любой задачи разбейте ее на элементарные части и решайте их по отдельности.
    В данном случае логично написать отдельную функцию безопасного копирования одного файла. Эта функция должна проверить есть ли целевое имя файла (если нет, то копирует), какого размера там файл (если такого-же до байта, то нужно проверить хеш и отказаться от копирования при совпадении, если другого, то нужно менять целевое имя или путь). С помощью pathlib можно подставлять расширение и быстро получить все файлы по маске в каталоге. Это позволит, например, быстро понять какой самый последний файл с именем вида 'file_name_00023.jpg' по маске 'file_name_*****.jpg', достать его цифровой хвостик, превратить в целое число, прибавить единицу и снова подставить в имя: Path('file_name_{last_index+1:05}.jpg').

    6. Подозреваю вы хотите написать безопасную дедупликацию картинок.
    • Прочитайте про хеш-функции и как они могут помочь сказать наверняка одинаковы ли два файла.
    • Прочитайте про символические ссылки. Это как ярлыки, но на уровне файловой системы и с файлами можно работать точно так же как с оригиналами. Такие ссылки позволят не копировать и не дублировать данные, когда требуется лишь как-то альтернативно сгруппировать их по каталогам.
    • Прочитайте про жесткие ссылки. Это выглядит как несколько имён одного файла в произвольных каталогах. Если хоть одно имя останется не удалённым, то и файл на диске будет. Данные хранятся один раз, а лежит файл как бы сразу в нескольких местах и нет никакого приоритета между ними.
    • Подумайте о журналировании. Иногда правильнее вместо реальных операций с файловой системой написать подробный журнал того, что вы хотите сделать в ней, а затем, по окончании опасного длительного процесса сборки этого журнала, можно утвердить и согласовать действия с пользователем, проанализировать список предстоящих операций и выполнить уже их спокойно или отказаться от них.
    Ответ написан
    1 комментарий
  • Промежуточное реле?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Там же 24 DC требуется. Конечно можно нагородить соплей из диодного моста и конденсаторов, но вы бы лучше реле подходящее подобрали и не мудрили.
    Ответ написан
    Комментировать
  • Как пользоваться методами в vk_api на python-e?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    А я не понимаю что вы не понимаете. И вашим коротким текстом вы не объяснили сути вопроса. Но даже не понимая сути вопроса и никогда не пользовавшись этим API я вот иду и пишу в гугле "vk-api python" и самой первой ссылкой получаю репозиторий на гитхабе.
    На главной странице проекта в ридми ссылка с примерами. Ну невозможно не увидеть.

    Я не понимаю, что вам не понятно. Где в моих действиях было что-то не очевидное? Как вообще отвечать на ваш вопрос?!
    Ответ написан
    4 комментария
  • В каком направлении двигаться для написания не сверх сложных ботов?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Судя по вопросу вам надо сперва хотя бы основы программирования освоить. на чем угодно, это не важно. И в совокупности это будет в разы сложнее и дороже по человекочасам, чем заплатить фрилансеру.
    Ответ написан
    9 комментариев
  • Реально ли работать на питоне не понимая сути декораторов?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    В общем пытаюсь учить питон и не могу никак понять суть декораторов.

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

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

    И нет, на декораторах свет клином не сошелся. Нужно понимать что в питоне функция - это объект первого рода и что это значит.
    Нужно понимать, что такое "замыкание" в контексте функционального программирования.
    Более того, нужно понимать что такое дескрипторы, как работают мета-классы и много-много всего такого.

    Нет, с этими знаниями не рождаются, их нужно осваивать.

    Декораторы - это очень простая концепция.
    Декоратор - это функция, которая принимает в качестве единственного аргумента какую-то функцию. Декоратор что-то делает с этой функцией (где-то регистрирует ее, документирует, оборачивает её вызов в другую функию) и возвращает её изменённую или другую функцию-обёртку.

    Что конкретно вам не понятно?

    Надо заметить, что Декоратор как паттерн проектирования имеет боле еширокий смысл. Декорировать можно объекты, классы, функции, даже модули (постольку, поскольку это тоже объекты). Учиться вам надо, сударь, и не ожидать, что всё прошьётся в мозг мгновенно. Быть программистом - это всегда учиться. Не останавливаясь.

    Примеров декораторов огромное множество: самые простые и понятные - это:
    - замер времени выполнения функции
    - кэширование результата
    - подстановка части аргументов (partial)
    Ответ написан
    4 комментария
  • Как обрезать фото человека с определнной точки(я хочу взять глаз человека и вокруг него обрезать), что читать?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Думаю надо использовать искуственный интелект да?

    Сначала нужно использовать естественный.
    Потом погуглить 2 минутки и вуаля
    Ответ написан
    Комментировать
  • Какой сервис выбрать для расчета маршрута и как создать собственный сервис с интерактивными картами?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    По требованиям все кроме третьего пункта (про стоимости) умеет osrm. К нему же идёт опенсорсный фронтенд, который можно допиливать.

    В обоих ваших вариантах вы написали какую-то чушь.
    Тайловый рендер разворачивается в докер-контейнере за 5 минут. Как и osrm. Сложно будет настроить все это под ваши хотелки, но можно.
    Бд - postgis. Есть тулза, которая импортит снапшот osm данных: https://wiki.openstreetmap.org/wiki/Osm2pgsql
    Можете придумать или поискать тег для указания стоимости проезда по дороге и везде проставить. По построенному osrm маршруту потом дополнительным запросом к бд можно вытащить дороги с ценами
    Ответ написан
    Комментировать
  • Как в pandas посчитать только новые данные, а не всю таблицу?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Держите два датафрейма:
    Один по размеру окна и при добавлении в него строчки в хвост удаляйте одну из головы.
    Второй накопительный, дуда добавляйте посчитанное. Так вы сохраните один и тот же код и для массовой обработки накопленных данных и для оконной риалтаймовой.
    Но тоже не очень эффективно, особенно при большом размере окна.

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

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    B={3,4,5,6}
    B=B|{-1,-2,-3}

    Откуда тут взяться 1 и 2?
    Print -> Множество B: {3, 4, 5, 6, -2, -3, -1} Почему пропало 1,2,

    А вот в C они будут из A:
    A={1,2,3,4}
    B={3,4,5,6}
    C=A|B

    Просто будьте внимательнее
    Ответ написан
    1 комментарий
  • Почему JSON.loads выдает ошибку?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Вот вы делаете объект-парсер html:
    soup = BeautifulSoup(loging.content, 'html.parser')

    а вот суёте его вместо строки в парсер josn'а:
    json_dat = json.loads(soup)
    Вот вам об этом говорится в сообщении об ошибке:
    TypeError: the JSON object must be str, bytes or bytearray, not BeautifulSoup

    Вы пытаетесь засунуть в бензобак автомобиля целиком бензоколонку. Не лезет.
    Вам нужно найти способ извлечь из бензоколонки бензин и поместить его в бензобак.
    Ответ написан
  • Почему Google карты на сайте отображаются белым?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    А с чего вы взяли, что это Google Maps?
    Тайлы берутся с яндекс-карт
    https://vec03.maps.yandex.net/tiles?l=map&v=20.05.27-0&x=2479&y=1284&z=12&scale=1&lang=ru_RU

    Причем они цветные. Цвет убирают накладыванием десатурации с помощью css
    Ответ написан
    1 комментарий
  • Как сгенерировать большое количество QR-кодов, около 100 000?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Я бы тупо заюзал какой-нибудь комманд-лайновый генератор QR-кодов и его результат засовывал бы в большую прозрачную PNG-картинку (можно было бы и в SVG через шаблонизатор, а потом печатать инкскейпом, но png хоть и менее эффективно но быстрее и проще). Так командная строка получает интервал номеров в аргументах, а на выходе даёт порцию файлов с QR-кодами. Останется их напечатать по очереди.
    Ответ написан
    Комментировать
  • Как правильно написать SQl запрос?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Вам нужно не группировку, а сортировку и оконную функцию.
    Но вы же не удосужились написать о какой БД речь, как вам помогать?

    На файрбёрде я уже не помню как такое делать. Тем более на современном. Давно не трогал.
    Хранимку бы по-быстрому запилил и сделал в цикле по отсортированному селекту проверку на равенство ФИО с предыдущим. Если равно, то обнулял бы фио
    Ответ написан