Хорошо, Хеннинг Махольм уже сказал это в своем комментарии, но он не объяснил, почему это на самом деле является лучшим решением.
Прежде всего, чтобы сказать: имея дело с плавающей точкой, мы должны всегда знать о возможных ошибках округления. Когда мы пишем [0.0, 0.1 .. 1.0]
, мы должны знать, что все эти числа, кроме первого, не будут в точном месте десятых. Где нам нужна эта определенность, мы вообще не должны использовать поплавки.
Но, конечно, существует много приложений, в которых мы довольны разумным определенным, скорость. Вот где поплавки великолепны. Одним из возможных применений такого списка было бы простое трапецеидальное числовое интегрирование:
trIntegrate f l r s = sum [ f x | x<-[l,(l+s)..r] ] * s - (f(l)+f(r))*s/2
давайте проверим это: trIntegrate ( \x -> exp(x + cos(sqrt(x) - x*x)) ) 1.0 3.0 0.1
=> 25.797334337026466 по сравнению с 25.9144 ошибка меньше, чем один процент. Конечно, не точно, но это присуще методу интеграции.
Предположим теперь, что диапазоны float были определены так, что они всегда заканчиваются при пересечении правой границы. Тогда было бы возможно (но мы не можем быть уверены в этом!), Что в сумме вычисляются только 20 значений, а не 21, потому что последнее значение x
оказывается равным 3.000000. Мы можем имитировать этот
bad_trIntegrate f l r s = sum [ f x | x<-[l,(l+s)..(r-s)] ] * s - (f(l)+f(r))*s/2
, после чего получим
bad_trIntegrate ( \x -> exp(x + cos(sqrt(x) - x*x)) ) 1.0 3.0 0.1
=> 21.27550564546988 urgh!
Это не имеет ничего общего со скрытием проблем с плавающим точка. Это всего лишь способ помочь программисту легче обойти эти проблемы. Фактически, противоположный результат [1, 3 .. 10] :: Float
помогает запомнить эти проблемы!
Измените это:
csvFile = open('log.csv', 'w', newline='')
К этому:
csvFile = open('log.csv', 'w', newline='', encoding='utf8')
Так как
open()
используется для открытия CSV-файла для чтения, файл по умолчанию будет декодирован в unicode с использованием системного кодирования по умолчанию (см.locale.getpreferredencoding()
). Чтобы декодировать файл с использованием другой кодировки, используйте аргумент кодировки open:import csv with open('some.csv', newline='', encoding='utf-8') as f: reader = csv.reader(f) for row in reader: print(row)
То же самое относится к записи в чем-то отличном от системного по умолчанию кодирования: укажите аргумент кодирования при открытии выходного файла.
Я полагаю, что ваша системная кодировка по умолчанию не является
utf8
. Вы можете проверить это следующим образом:import locale locale.getpreferredencoding()
Надеюсь, что это поможет!
Похоже, модуль csv ожидает строки, а не bytes
. Таким образом, вы можете дешифровать свой bytes
перед их передачей:
cell.text.encode('ascii', 'replace').decode('ascii')
csvRow.append(cell.text.encode('ascii', 'replace')
наcsvRow.append(cell.getText())
– patlatka 13 July 2018 в 15:55