Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 14, 2017 18:04:37

Moder5ly
Зарегистрирован: 2017-11-14
Сообщения: 1
Репутация: +  0  -
Профиль   Отправить e-mail  

Создание большого (очень) количества папок

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

 import hashlib
import os
i = 0.060000000000000000000000000000
end = 0.0666666666666666666666666666667
while i <= end:
    formatted = str(format(i, ".30f"))
    string = hashlib.sha224(formatted).hexdigest()
    if(os.path.exists("56/" + str(string)) == False):
        os.mkdir('56/' + str(string))
    i = i + 0.000000000000000000000000000001
print "OK"
Значения i, end менять пробовал, но проблема не решилась.

Отредактировано Moder5ly (Ноя. 14, 2017 18:06:07)

Офлайн

#2 Ноя. 14, 2017 21:57:30

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Создание большого (очень) количества папок

слишком много нулей после точки, более детально смотреть тут https://docs.python.org/3/tutorial/floatingpoint.html и тут https://docs.python.org/3/library/sys.html
пример:

 import sys
print(0.5+sys.float_info.epsilon)
>>>
0.5000000000000002
если вкратце то работа с любыми числами с плавающей запятой выполняется с погрешностями.
Машинный эпсилон - это минимальная разница между числами, которую компьютер в состоянии различить.
Это конечно не совсем так, числа меньше FLT_EPSILON вполне представимы в float и вы вполне можете с ними работать. Но плотность чисел представимых в float не постоянна. Расстояние между 2 такими соседними числами может быть меньше FLT_EPSILON. А у вас инкремент порядка 10**-30, вот пайтон и ложит болт на ваш инкремент. И цикл у вас создает постоянно одну и туже папку.
Так что вам нужно менять алгоритм вашей программы.
например использовать decimal както так:
 import hashlib
import os
from decimal import Decimal, getcontext
getcontext().prec = 29
i = Decimal(0.060000000000000000000000000000).quantize(Decimal('0.000'))
end = Decimal(0.0666666666666666666666666666667)
while i <= end:
    formatted = str(format(i, ".30f"))
    string = hashlib.sha224(formatted.encode('UTF-8')).hexdigest()
    print(i, formatted, string)
    #if(os.path.exists("56/" + str(string)) == False):
        #os.mkdir('56/' + str(string))
    i = i + Decimal(0.000000000000000000000000000001)
print ("OK")
>>>
0.060 0.060000000000000000000000000000 8fa7b78dbccdcc900620e4453060774facd36bd0a446f1f91176d9dd
0.060000000000000000000000000001 0.060000000000000000000000000001 4e4065c98754420c8f49e4dbbb542790bcf25cbd8b391b8bafd61e39
0.060000000000000000000000000002 0.060000000000000000000000000002 a3119e54b99f91eb8151eefd5f69bc68339e0ca47f609c16e633c0d9
.....
подробнее https://docs.python.org/3/library/decimal.html



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Ноя. 14, 2017 22:08:59)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version