一把用于自定义数字系统数量的瑞士军刀。
Evgueni Antonov 2023。
该模块是在Python 3.10.6,PIP 23.1.2上创建和测试的。
第一次出版于2023年5月。
pip3 install custom-numbers
# or
python3 -m pip install custom-numbers
有关如何使用它的详细信息,请参见下面的“使用”部分。
from custom_numbers import custom_numbers as cn
my_custom_numeral_system = cn.CustomNumeralSystem("paf")
my_number = cn.CustomNumber(my_custom_numeral_system, "a")
# Now if you type in REPL:
# help(cn)
# You will get the help for the module and the classes.
该软件包包含一个模块,其中很少有类,可以帮助您声明由具有自定义基础的自定义符号制成的自定义数字系统。这听起来很奇怪,实际上这就是它的外观:
注意:不支持子系统,我不打算实施此功能。
注意:此模块仅支持自定义整数号码。自定义的浮点数不支持,也永远不会。
让我们从您已经知道的东西开始 - 二进制号码。这些仅由零和一个制成,因此基部为2。
示例:1100101
这实际上是90年代真正酷的歌曲的标题。同样是1100101二进制,转换为小数为101 (一百个),就像(二进制) 10 2 == 2 10 (十进制)一样。
现在 - 十六进制的数字 - 这些由数字0、1、2、3、4、5、6、7、8、9和字母A,B,C,D,E,F的数字制成,其基数为16。
因此,十六进制数字看起来像这样:
F 16 == 15 10,10 16 == 16 10 ,F0 16 == 240 10
另一个众所周知的数字系统是八进制系统,仅由零到7和第8位数字组成,但我们现在会跳过这个。
最后,我们从小就知道的十进制系统的基础为10,并且由数字从零到9的数字制成。
好的,到目前为止,您已经熟悉最广泛使用的数字系统 - 二进制,八进制,十进制和十六进制。
让我们从重新定义二进制系统开始。因此,它确实有2个基础,我们不会改变这一点。但是,如何使用0和1使用p和a ?因此, P是我们的新零, A将是我们的新零。因此,正如我们通常会写1100101的那样,现在将写为Aappapa 。令人困惑,对吧?但是,什么 - 它仍然是二进制系统,我们只是更改了符号。
但是现在,疯狂的东西怎么样 - 使用符号p,a,f作为数字的数字系统,f, f将为2个小数, p为0小数。所以:
AA 3 == 4 10 ,AF 3 == 5 10 ,FP 3 == 6 10
现在让我们看看这一点:
from custom_numbers import custom_numbers as cn
sys3 = cn.CustomNumeralSystem("paf")
num3 = cn.CustomNumber(sys3, "aa")
num10 = num3.to_decimal()
print(num10) # Prints "4"
测试这些类是否按预期工作的最佳方法是用我们都知道的符号声明数字系统:
from custom_numbers import custom_numbers as cn
sys2 = cn.CustomNumeralSystem("01")
num2 = cn.CustomNumber(sys2, "1100101")
num10 = num2.to_decimal()
print(num10) # Prints "101"
sys16 = cn.CustomNumeralSystem("0123456789abcdef")
num16 = cn.CustomNumber(sys16, "f0")
num10 = num16.to_decimal()
print(num10) # Prints "240"
到目前为止,一切都很好。现在,让我们完全发疯,并声明一个基本的Greather系统,大于16,并且是数字的完全怪异的符号。我们实际上可以做到这一点,甚至可以完全疯狂的事情:
sysN = cn.CustomNumeralSystem("kje5nCs21Q9vW0KMqc")
注意:自定义数字很敏感!所以n!= n !
注意:有一些禁止字符,这些字符不能在数字系统中使用,也不能在数字中使用。您总是可以使用CustomNumeralSystem类的Forbidden_Characters属性来将它们作为字符串作为字符串。
在用于基本验证需求的CustomNumeralSystem类中,实现了平等和IQEELATY PYTHON运算符,因此您可以比较两个对象。
但是,比较将按代表数字的字符的列表(基本上是字符串),而不是标准的python对象(参考)比较。
sys1 = cn.CustomNumeralSystem("paf")
sys2 = cn.CustomNumeralSystem("paf")
# The two objects are different, despite being initialized with
# the same value
id(sys1) == id(sys2) # False
# However the set of characters (the digits) is the same, the
# base is the same, so I accept they are the same numeral systems
sys1 == sys2 # True
# And you could also test for inequality
sys1 = cn.CustomNumeralSystem("paf")
sys2 = cn.CustomNumeralSystem("paz")
sys1 != sys2 # True
也支持签名的自定义号码。
sysN = cn.CustomNumeralSystem("paf")
numN1 = cn.CustomNumber(sysN, "-a") # A negative number
numN2 = cn.CustomNumber(sysN, "a") # A positive number
numN3 = cn.CustomNumber(sysN, "+a") # A positive number
基本数学操作是支持的槽标准Python操作员。
sysN = cn.CustomNumeralSystem("paf")
numN1 = cn.CustomNumber(sysN, "-a")
numN2 = cn.CustomNumber(sysN, "a")
numN3 = cn.CustomNumber(sysN, "+a")
# Comparisson
numN1 == numN2
numN1 != numN2
numN1 > numN2
numN1 < numN2
numN1 >= numN2
numN1 <= numN2
# Basic mathematical operations
numN1 + numN2 # Addition
numN1 += numN2 # Augmented addition
numN1 - numN2 # Subtraction
numN1 -= numN2 # Augmented subtraction
numN1 // numN2 # Floor division
numN1 / numN2 # NOTE: This will perform floor division as well!
# as floating point numbers are not supported by this class and will
# never be.
numN1 * numN2 # Multiplication
numN1 ** numN2 # Power
numN1 % numN2 # Modulo division
abs(numN) # Absolute value
使用迭代器:
sysN = cn.CustomNumeralSystem("paf")
it = cn.GearIterator(sysN, 0, 2)
next(it) # "p" # "p" assumes to be the analog of the zero
next(it) # "a"
next(it) # "f"
next(it) # "ap"
next(it) # "aa"
# and so on. You get the idea.
# The iterator could also be initialized with an init_value which is
# de-facto a custom number from the chosen CustomNumeralSystem,
# but for convenience I left the number to be a string, as you may
# wish or not to initialize at all:
it = cn.GearIterator(sysN, 0, 2, "af")
注意:如果初始化,迭代器将从给定的init_value剥离任何领先的“零”(可以说)。
定义并声明一个自定义数字系统。
CustomNumeralSystem(digits: str)
Args:
digits: The symbols to be used as digits. The string length defines
the numeral system base.
特性:
forbidden_characters -> str
base -> int
方法:
valid_number(number: str) -> bool
Tests if the given "number" is valid for the current numeral system.
Should not contain forbidden characters.
Should contain only characters defined in the numeral system.
定义并从自定义数字系统中声明数字。
CustomNumber(numeral_system: CustomNumeralSystem, value: str)
Args:
numeral_system: A previously defined custom numeral system.
value: The value (the number itself).
特性:
init_value -> str
Returns the initial value the class was initialized with.
方法:
digit_to_int(digit: str) -> int
Converts the given digit from the custom numeral system to a
decimal integer.
to_decimal() -> int
Converts the current number value to a decimal integer.
从第一个数字开始(零等效)或从给定的init_value开始,迭代自定义数字系统的数量。
短暂地模拟旧齿轮柜台,例如旧车里程表。
GearIterator(numeral_system: CustomNumeralSystem, min_length: int = 0, max_length: int = 0, init_value: str = "")
Args:
numeral_system: Custom numeral system. Mind the order of symbols!
min_length: Minimum length, default is zero.
max_length: Maximum length, default is zero - means no limit.
init_value: Value to initialize with.
特性:
combinations -> int
Returns the number of possible combinations (iterations).
该类实现Python上下文管理协议。