Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 25, 2017 22:53:40

shiroi
Зарегистрирован: 2017-10-25
Сообщения: 23
Репутация: +  0  -
Профиль   Отправить e-mail  

система счисления с основанием n

Вечер добрый всем. Может кто подсказать, как написать функцию, которая бы переводила введенное десятичное число в систему счисления с основанием от 2 до 36?Заранее благодарю за любую помощь

Офлайн

#2 Окт. 26, 2017 03:55:47

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

система счисления с основанием n

Переводит число из десятичной системы в любую систему в пределах [2; +inf).

Add
Для нуля забыл учесть, ниже поправил версию.



Отредактировано py.user.next (Окт. 26, 2017 11:14:28)

Прикреплённый файлы:
attachment numbase.tar.bz2 (722 байта)

Офлайн

#3 Окт. 26, 2017 11:00:26

shiroi
Зарегистрирован: 2017-10-25
Сообщения: 23
Репутация: +  0  -
Профиль   Отправить e-mail  

система счисления с основанием n

py.user.next
Переводит число из десятичной системы в любую систему в пределах [2; +inf).
оо,спасибо большое за помощь

Офлайн

#4 Окт. 26, 2017 11:15:02

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

система счисления с основанием n

Исправил версию, добавив обработку нуля в числе.

tags: system base



Отредактировано py.user.next (Окт. 27, 2017 10:46:40)

Прикреплённый файлы:
attachment numbase.tar.bz2 (764 байта)

Офлайн

#5 Окт. 26, 2017 14:55:19

shiroi
Зарегистрирован: 2017-10-25
Сообщения: 23
Репутация: +  0  -
Профиль   Отправить e-mail  

система счисления с основанием n

py.user.next
Спасибо еще раз. Возникла проблема,при вводе с клавиатуры числа 34 и при переводе его в 8 систему, выводит это : 4.02.0, хотя должен 42. И так со всеми, особенно если вводимое число дробное.

Прикреплённый файлы:
attachment trying.rar (408 байт)

Офлайн

#6 Окт. 26, 2017 15:20:46

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

система счисления с основанием n

Она не переводит вещественные (дробные) числа, только целые положительные. Это сделано специально. Это общая задача, все остальные варианты строятся на её решении.
1) Дробные числа переводятся по частям: сначала число разделяется на целую и дробную части; затем переводится целая часть; затем переводится дробная часть; затем переведённые части соединяются обратно через точку.
2) То же самое с отрицательными числами: сначала отделяется знак; затем число переводится; затем знак присоединяется обратно к переведённому числу.

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

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

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



Отредактировано py.user.next (Окт. 26, 2017 15:52:48)

Офлайн

#7 Окт. 26, 2017 15:42:10

shiroi
Зарегистрирован: 2017-10-25
Сообщения: 23
Репутация: +  0  -
Профиль   Отправить e-mail  

система счисления с основанием n

py.user.next
Она не переводит вещественные (дробные) числа, только целые положительные. Это сделано специально. Это общая задача, все остальные варианты строятся на её решении.1) Дробные числа переводятся по частям: сначала число разделяется на целую и дробную части; затем переводится целая часть; затем переводится дробная часть; затем переведённые части соединяются обратно через точку.2) То же самое с отрицательными числами: сначала отделяется знак; затем число переводится; затем знак присоединяется обратно к переведённому числу.И тут ты понимаешь, что отрицательное число может быть как целым, так и дробным. Целое раскладывать не нужно, а дробное - нужно. То есть уже всё запутывается, поэтому это всё нельзя в одну функцию загонять. Может получиться так, что у тебя в программе будут только целые числа встречаться, а функция будет пытаться постоянно что-то разложить, затрачивая время на это, хотя это не надо.Можно написать функцию-обёртку, которая определяет вид поданного числа, раскладывает его соответствующим образом (если надо), потом использует эту базовую функцию для перевода числа в заданную систему счисления, а потом соединяет переведённые части обратно тем же образом, которым они разделялись.То есть получается, что у тебя есть разные функции, и каждая из этих функций занимается только своим делом. Одна функция готовит части числа, другая функция переводит каждую часть определённым образом. Таким образом в функциях соблюдается принцип функциональной прочности модуля: одна функция - одно действие. Дед Мороз, который сам танцует, сам поёт, сам подарки раздаёт, - в программировании не приветствуется.
охох, спасибо большое за такой ответ, буду тогда пытаться написать все это правильно

Офлайн

#8 Окт. 28, 2017 02:04:47

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

система счисления с основанием n

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

  
def decimal_fraction_to_base(number, base):
    out = None
    if isinstance(number, int):
        out = decimal_to_base(abs(number), base)
        if number < 0:
            out = '-' + out
    elif isinstance(number, float):
        parts = str(number).partition('.')
        ipart = int(parts[0].strip('-'))
        fpart = int(parts[-1])
        oipart = decimal_to_base(ipart, base)
        ofpart = decimal_to_base(fpart, base)
        out = oipart + '.' + ofpart
        if number < 0:
            out = '-' + out
    return out

  
>>> import numbase
>>>
>>> numbase.decimal_fraction_to_base(12345.255, 36)
'9(18)(33).73'
>>> numbase.decimal_fraction_to_base(12345.255, 16)
'3039.(15)(15)'
>>> numbase.decimal_fraction_to_base(-12345, 16)
'-3039'
>>> numbase.decimal_fraction_to_base(-12345.255, 16)
'-3039.(15)(15)'
>>>

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



Отредактировано py.user.next (Окт. 28, 2017 02:13:36)

Офлайн

#9 Окт. 28, 2017 20:40:42

shiroi
Зарегистрирован: 2017-10-25
Сообщения: 23
Репутация: +  0  -
Профиль   Отправить e-mail  

система счисления с основанием n

py.user.next
Еще раз спасибо за помощь. Вопрос если можно, а как вывести вместо ‘9(18)(33).73’ числа от 0-9 а потом буквенные значения?

Офлайн

#10 Окт. 29, 2017 03:33:59

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

система счисления с основанием n

Мы делаем дополнительный транслятор цифр любой системы счисления в любые символы и встраиваем его в функцию преобразования вещественных чисел

  
>>> import re
>>> 
>>> def translate_base_digits(number):
...     digits_map = {
...         '(10)': 'a', '(11)': 'b', '(12)': 'c',
...         '(13)': 'd', '(14)': 'e', '(15)': 'f',
...         '(16)': 'g', '(17)': 'h', '(18)': 'i',
...         '(19)': 'j', '(20)': 'k', '(21)': 'l',
...         '(22)': 'm', '(23)': 'n', '(24)': 'o',
...         '(25)': 'p', '(26)': 'q', '(27)': 'r',
...         '(28)': 's', '(29)': 't', '(30)': 'u',
...         '(31)': 'v', '(32)': 'w', '(33)': 'x',
...         '(34)': 'y', '(35)': 'z',
...     }
...     def trans(digit):
...         return digits_map.get(digit, digit)
...     out = re.sub(r'\(\d+\)', lambda mo: trans(mo.group()), number)
...     return out
... 
>>> def decimal_fraction_to_base(number, base):
...     out = None
...     if isinstance(number, int):
...         out = decimal_to_base(abs(number), base)
...         if number < 0:
...             out = '-' + out
...     elif isinstance(number, float):
...         parts = str(number).partition('.')
...         ipart = int(parts[0].strip('-'))
...         fpart = int(parts[-1])
...         oipart = decimal_to_base(ipart, base)
...         ofpart = decimal_to_base(fpart, base)
...         out = oipart + '.' + ofpart
...         if number < 0:
...             out = '-' + out
...     out = translate_base_digits(out)
...     return out
... 
>>> from numbase import decimal_to_base
>>> 
>>> decimal_fraction_to_base(12345.255, 36)
'9ix.73'
>>> decimal_fraction_to_base(12345.255, 16)
'3039.ff'
>>> decimal_fraction_to_base(-12345, 16)
'-3039'
>>> decimal_fraction_to_base(-12345, 36)
'-9ix'
>>> decimal_fraction_to_base(-12345.255, 16)
'-3039.ff'
>>> decimal_fraction_to_base(-12345.255, 36)
'-9ix.73'
>>>
В идеале, у тебя должны быть отдельные функции, в которые подаются данные, поступающие из других функций или передающиеся напрямую. Здесь же транслятор цифр фиксирует данные (какие цифры в какие буквы) внутри функции, тогда как в идеале маппинг должен передаваться в функцию снаружи, чтобы можно было его дополнить в любой момент или видоизменить (сделать больше букв всяких, поменять регистр букв и так далее).
Почему нельзя сделать всё с самого начала на буквах? Потому что букв самих по себе немного, а базовая функция работает с любыми системами счисления (это математический подход, в котором системы счисления не ограничены какой либо базой).
В твоём случае надо ограничить систему счисления 36-ю, а где-то понадобится система счисления 1000, поэтому в ней никаких букв не хватит. Вот поэтому в общей функции используются скобки с числами, а всё остальное становится частными случаями и реализуется каждый раз по-своему.



Отредактировано py.user.next (Окт. 29, 2017 03:39:49)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version