Ответы пользователя по тегу Python
  • Как сделать запрос sqlite?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Правильнее так:
    cur.execute('INSERT INTO Cars VALUES (?, ?, ?)',  (123, 'Belaz', 321))

    cur.execute('INSERT INTO Cars VALUES (?, ?, ?)',  a)

    Это, в отличие от формирования запроса в виде строки, убережет вас от SQL-инъекций.
    Ответ написан
    Комментировать
  • Странное поведение pycharm?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Сейчас я проясню ситуацию=).
    Текст бывает либо в какой-то кодировке (cp1251, utf-8, win866, ascii, и т.д.), тогда это байты; либо в юникоде (это, как бы, абстрактное представление символов), тогда это строки из абстрактных юникодовых символов.
    Все файлы, потоки ввода-вывода и т.д. у нас в компьютере работает с байтами, а не с абстрактными юникодовыми символами. Это значит, что перед выводом в файл или консоль должно производиться кодирование юникода в конкретную кодировку.
    Кодировка -- это способ представить байтами абстрактных символов юникода. Каждый юникодовый символ, в зависимости от кодировки, будет задаваться одним или более байтом. Некоторые абстрактные символы не поддерживаются некоторыми кодировками.

    Так, например, кодировка ascii поддерживает только стандартные 128 символов и при попытке конвертировать в неё (явно или неявно) букву "Ж", будет такая же ошибка как у вас. Надо полагать метод parse в вашем случае возвращает юникод, а оператор print делает неявное преобразование в кодировку по умолчанию (ascii, судя по сообщению об ошибке).
    Осталось выяснить в каких случаях как определяется кодировка по умолчанию.
    Артём Клименко правильно предложил в своём ответе проверить что берётся в качестве кодировки по умолчанию в том и другом случае.
    Однако решением проблемы должно быть явное преобразование текста в нужную кодировку. Я в таких случаях придерживаюсь следующих правил:
    • Всё, что приходит в программу, привожу в юникод (если это не произошло неявно в той библиотеке, посредством которой я получил данные).
    • В программе работаю с текстом только в юникоде (если речь не идёт о каких-то низкоуровневых операциях над байтами, вроде парсинга протоколов и прочего.
    • Перед выводом конвертирую текст в нужную кодировку или настраиваю потоки вывода на автоматическое преобразование.
    • Когда не понятно в какой кодировке делать вывод, руководствуюсь следующими правилами:
      • Выходной поток -- это виндовый stdout и в нём не задана кодировка (bat-файлы, консоль) -- cp866
      • Файлы, БД и прочее, что поддерживает юникод и сделано правильно -- UTF-8
      • Когда в винде не помогают пердыдущие пункты -- cp1251
      • В других операционках utf-8.


    Подчеркиваю. Если выходной поток сконфигурирован на ascii, а у нас в программе могут попасться не-ascii символы, то нужно приводить текст в какую-то кодировку (см выше)), а иначе ничего не трогаем и пишем юникод.
    Ответ написан
    Комментировать
  • Не переходит в цикл, хотя условия выполнены. Где ошибка?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    В исходном коде много странных мест. Например, странным и опасным образом опущенны запятые в описании словаря, опасное применение переменной dobav в ветке else... Это всё ведёт к небезопасному коду в плане понимания и будущих модификаций. Очевидна нехватка опыта.

    Насчет приоритета операций вам уже ответили, но давайте попробуем провести поэтапный для ясности рефакторинг вашего кода.
    Вот чему эквивалентно тело вашей функции:
    def print_mimic(mimic_dict, word):
        bred = []
        x = 0
        dobav = word
        while x < 200:
            if x == 0 or dobav in mimic_dict:
                dobav = random.choice(mimic_dict[dobav])
            else:
                dobav = random.choice(mimic_dict[" "])
            bred.append(dobav)
            x += 1
        print (bred)
        return bred

    Я понятия не имею что это за код и для чего он. Предыдущий рефакторинг я сделал оставив код эквивалентным исходному (за исключением исправления очевидных ошибок). Можно предположить, что в коде есть ещё ряд логических ошибок. Возможно поведение по ветке "x == 0" не должно отличаться от поведения по ветке else условия "dobav in mimic_dict", а вместо константы " " следовало тоже поставить word. Тогда код становится гораздо более простым, понятным и элегантным.
    def print_mimic(mimic_dict, word):
        bred = []
        dobav = word
        for x in range(200):
            dobav = random.choice(mimic_dict.get(dobav, mimic_dict[" "])) 
            bred.append(dobav)
    
        print (bred)
        return bred
    Ответ написан
    1 комментарий
  • Python: почему в процессе суммирования десятичных в середине интервала появляется ошибка?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    Вообще-то описанную проблему можно проиллюстрировать проще:
    >>> 0.5+2.7, 0.4+2.8
    (3.2, 3.1999999999999997)

    Это нормальная ситуация для чисел с плавающей точкой. Она связана с тем, что для любой системы счисления (двоичной, десятичной, троичной) есть числа, которые нельзя записать в виде конечной последовательности n-ричных разрядов. Например, в десятичной системе число 1/3 будет выглядеть как бесконечная последовательность троек после запятой. Если мы остановимся, то получим не 1/3 а что-то поменьше. Зато в троичной системе это число замечательно представляется как 0.1. Одна девятая в троичной системе равна 0.01.
    Та же проблема, например, у десятичного числа 0.2 при переводе в двоичную систему:
    2/10==1/5==1/8+1/16+1/128+1/256+1/2048+1/4096+(...)==0,00110011(0011)[в двоичной системе]
    Как видим это периодическое число и двоичные разряды "0011" повторяются в нём после запятой бесконечно.
    Компьютерное представление чисел с плавающей точкой подразумевает их хранение в конечном количестве двоичных разрядов. Это значит, что многие вполне нормально записываемые в десятичной форме дробные числа просто не могут абсолютно точно храниться в компьютере (если речь идёт о floatpoint).

    Имеенно поэтому программистов учат на первом курсе института никогда не сравнивать числа с плавающей точкой на строгие равенство и неравенство. С учетом погрешности из-за округления двоичных разрядов это просто бессмысленно и некорректно.
    Зато, вместо сравнения на равенство, можно сравнивать abs(a-b)<eps, где a и b -- числа в формате с плавающей точкой, а eps -- это некоторая пренебрежительно малая величина. Вообще-то, думаю, можно вычислить даже минимальное значение этой величины, чтобы она покрыла все неприятности с округлением двоичных разрядов.
    Ответ написан
    Комментировать
  • Почему «срабатывает» выражение?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст

    У вас лишний обратный слеш а авражении "\" и строка не сырая. Короче, правильно леоать так:
    re.match(r'/link/abcd(/.*)?$','/link/abcd/')
    Хвостовой слеш не обязателен, но если он есть, после него допускаются любые символы в любом количестве, в том числе нулевом.

    Ответ написан
    Комментировать