Форум сайта python.su
py.user.next
out = re.sub(r'\(\d+\)', lambda mo: trans(mo.group()), number), re.sub это как я понимаю функция замены?а можно ее заменить например s.replace?
Офлайн
shiroiНет. str.replace() ходит всегда по всей строке и для каждой цифры надо будет вызывать str.replace() снова. А re.sub() идёт один раз по строке и для каждой встреченной цифры делает сразу её замену. Замена у re.sub() умная (это распространённый шаблон для многих языков) и делает не просто замену строки на строку, а делает замену строки на результат функции, в которую передаётся найденная подстрока. Таким образом мы можем использовать отображение одних строк на другие (в виде словаря с парами), чтобы замена происходила по этому отображению. А в str.replace() можно только одну строку на одну строку заменять, поэтому она здесь не подходит. То есть re.sub() может искать, на что заменить совпавшую подстроку, а str.replace() может только тупо заменить определённую строку на определённую строку.
а можно ее заменить например s.replace?
>>> import re >>> >>> re.sub(r'.', lambda mo: str(int(mo.group()) ** 2), '1234') # находим квадрат каждой цифры и пишем в результат '14916' >>> >>> re.sub(r'.', lambda mo: mo.group() * 3, '1234') # утраиваем каждую цифру и пишем в результат '111222333444' >>> >>> re.sub(r'(..)(..)', lambda mo: str(sum(map(int, mo.groups()))), '1234') # находим пары цифр, складываем двузначные числа и пишем в результат '46' >>> >>> re.sub(r'.', lambda mo: print('see', mo.group()) or mo.group() * 2, '1234') # выводим найденные цифры, удваиваем их и пишем в результат see 1 see 2 see 3 see 4 '11223344' >>>
Отредактировано py.user.next (Окт. 29, 2017 04:44:04)
Офлайн
py.user.nextэх, плюсов то много, правда у меня условие что не могу использовать сторонние библиотеки, поэтому re.sub не могу использовать
Офлайн
Офлайн
py.user.next
почти все правильно работает, кроме правой части, если после точки вводить что-нибудь, отличное от левой части, то он начинает неправильно считать, например: 12345.12345 в 36 он выводит правильно, 9ix.15wx, а вот если 12345.54321, то он выводит 9ix.15wx вместо 9ix.1920007162620232434
Офлайн
shiroiДа я просто неправильно посчитал дробную часть, Забыл, как это делается (давно делали, где-то в 2002-м, если не в 2000-м
почти все правильно работает, кроме правой части
shiroihttps://numsys.ru/
а вот если 12345.54321, то он выводит 9ix.15wx вместо 9ix.1920007162620232434
Отредактировано py.user.next (Окт. 29, 2017 13:35:17)
Офлайн
py.user.next
ограничение 8 знаков после точки на выводе
Офлайн
shiroiВидишь, надо точно знать, чтобы сначала юнит-тесты написать. Без юнит-тестов не будешь точно знать, работает ли функция без ошибок. Она же большая, всё в голове держать заманаешься, поэтому делаются юнит-тесты, которые её запускают и проверяют результат сразу. Если результаты всех тестов правильные, то он просто пишет точки. Если результат неправильный где-то, то он сразу пишет сообщение об ошибке (сбой теста).
ограничение 8 знаков после точки на выводе
python3 -m pytest
Отредактировано py.user.next (Окт. 29, 2017 13:45:33)
Офлайн
Да, видимо, в питоне такой алгоритм не прокатит из-за слишком малой точности у вещественных чисел
[guest@localhost numbase_mono]$ python3 -m pytest
================================== test session starts ===================================
platform linux -- Python 3.6.1, pytest-3.1.1, py-1.4.34, pluggy-0.4.0
rootdir: /home/guest/prog/tests/py/numbase_mono, inifile:
plugins: mock-1.6.2, cov-2.4.0
collected 14 items
test_numbase.py .F............
======================================== FAILURES ========================================
__________________________________ test_fraction_values __________________________________
def test_fraction_values():
lst = (
(1.1, 2, '1.000110011'),
(10.5, 2, '1010.1'),
(255.255, 16, 'ff.4147ae147a'),
(12345.12345, 36, '9ix.4fzolfdnfyd'),
(12345.54321, 36, '9ix.jk007gql696'),
)
for i1, i2, o in lst:
> assert f(i1, i2) == o
E AssertionError: assert '9ix.4fzolfdl0g' == '9ix.4fzolfdnfyd'
E - 9ix.4fzolfdl0g
E ? ^^^
E + 9ix.4fzolfdnfyd
E ? ^^^^
test_numbase.py:26: AssertionError
========================== 1 failed, 13 passed in 0.05 seconds ===========================
[guest@localhost numbase_mono]$
Отредактировано py.user.next (Окт. 29, 2017 16:30:15)
Офлайн
В общем, небольшие вещественные числа она правильно вычисляет, но когда число становится больше по точности (когда исходная дробь растёт), начинаются глюки.
Поковырял это математически, можно там замутить рекурсивную функцию, если в питоне точности не хватает.
Например:
0.12d == 0.(1EB85)h
Приводим к дробному виду
12 / 100 = x / 256
Находим x
x = (12 * 256) / 100 = 30.72
Получаем равное соотношение (слева в десятичной системе, справа - в 16-ричной)
12 / 100 = 30.72 / 256
Дальше 30.72 переводим по частям в 16-ричную систему
30 = 1E
0.72 = 0.(B851E) (это так же переводится - приводится к дроби и так далее 72 / 100 = x / 256 … )
Потом склеиваем 1E и 0.(B851E) и получаем x в 16-ричной системе
0.1EB851E
Отредактировано py.user.next (Окт. 30, 2017 01:56:59)
Прикреплённый файлы: numbase_mono.tar.bz2 (1,1 KБ)
Офлайн