Un couteau à armure suisse pour le nombre de systèmes de chiffres personnalisés.
Evgueni Antonov 2023.
Ce module a été créé et testé sur Python 3.10.6, PIP 23.1.2.
Publié pour la première fois en mai 2023.
pip3 install custom-numbers
# or
python3 -m pip install custom-numbers
Pour plus de détails sur la façon de l'utiliser, consultez la section d'utilisation ci-dessous.
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.
Ce package contient un module avec quelques classes faites pour vous aider à déclarer un système de chiffres personnalisé, en symboles personnalisés avec une base personnalisée. Comme cela peut sembler étrange, en réalité, c'est à quoi cela ressemble:
Remarque: les sous-systèmes ne sont pas pris en charge et je ne prévois pas d'implémenter cette fonctionnalité.
Remarque: Ce module prend en charge uniquement les numéros entiers personnalisés. Les numéros de points flottants personnalisés ne sont pas pris en charge et ne le seront jamais.
Commençons par quelque chose que vous connaissez déjà - un numéro binaire. Ceux-ci sont faits uniquement de zéros et de ceux et donc la base est 2.
Exemple: 1100101
Et c'est en fait le titre d'une chanson vraiment cool des années 90. Aussi 1100101 binaire, converti en décimal est de 101 (cent un), tout comme (binaire) 10 2 == 2 10 (décimal).
Maintenant - un nombre hexadécimal - ceux-ci sont faits des chiffres 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 et les lettres A, B, C, D, E, F et ont une base de 16.
Donc, un numéro hexadécimal ressemble à ceci:
F 16 == 15 10 , 10 16 == 16 10 , f0 16 == 240 10
L'autre système de chiffres bien connu est le système octal, composé uniquement de chiffres de zéro à sept et de base 8, mais nous sauterons celui-ci maintenant.
Et enfin, le système décimal que nous connaissons tous depuis l'enfance a une base de 10 et est fait des chiffres de zéro à neuf.
D'accord, jusqu'à présent, vous connaissez les systèmes numériques les plus utilisés - le binaire, l'octal, la décimale et l'hexadécimal.
Commençons par redéfinir le système binaire. Il a donc une base de 2 et nous ne changerons pas cela. Cependant, que diriez-vous au lieu d'utiliser 0 et 1 pour utiliser P et A à la place? D. P serait donc notre nouveau zéro et un serait notre nouveau. Par conséquent, comme nous l'écririons normalement 1100101, cela serait maintenant écrit comme Aappapa . Déroutant, non? Mais donc quoi - c'est toujours un système binaire, nous avons juste changé les symboles.
Mais maintenant, que diriez-vous de quelque chose de plus fou - un système de chiffres avec une base de 3, en utilisant les symboles P, A, F comme chiffres, donc F serait 2 décimaux, P serait 0 décimale. Donc:
Aa 3 == 4 10 , af 3 == 5 10 , fp 3 == 6 10
Voyons maintenant cela en action:
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"
La meilleure façon de tester si les classes fonctionnent comme prévu est de déclarer les systèmes numériques avec les symboles que nous connaissons tous:
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"
Jusqu'ici, tout va bien. Voyons maintenant totalement fou et déclarons un système avec un great de base que 16 et un ensemble de symboles totalement étranges pour les chiffres. Et nous pouvons réellement faire ça et encore plus de trucs totalement fous:
sysN = cn.CustomNumeralSystem("kje5nCs21Q9vW0KMqc")
Remarque: les numéros personnalisés sont sensibles à la casse !! Alors n! = N !!
Remarque: Il existe des caractères interdits, qui ne peuvent pas être utilisés dans un système de chiffres et ne peuvent pas être utilisés dans un nombre. Vous pouvez toujours les obtenir en tant que chaîne en utilisant la propriété Forbidden_Characters de la classe CustomNumealSystem .
Dans la classe CustomNumealSystem pour les besoins de validation de base, les opérateurs Python d'égalité et d'Iequality ont été mis en œuvre, afin que vous puissiez comparer deux objets.
Cependant, la comparaison serait par la liste (essentiellement la chaîne) des caractères représentant les chiffres, plutôt que la comparaison de l'objet Python standard (référence).
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
Les numéros personnalisés signés sont également pris en charge.
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
Les opérations mathématiques de base sont des opérateurs Python standard de creux pris en charge.
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
Utilisation de l'itérateur:
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")
Remarque: Si elle est initialisée, l'itérateur supprimera tous les "zéros" de premier plan (pour ainsi dire) à partir de l'init_value initit donné.
Définit et déclare un système de chiffres personnalisé.
CustomNumeralSystem(digits: str)
Args:
digits: The symbols to be used as digits. The string length defines
the numeral system base.
PROPRIÉTÉS:
forbidden_characters -> str
base -> int
Méthodes:
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.
Définit et déclare un numéro à partir d'un système de chiffres personnalisé.
CustomNumber(numeral_system: CustomNumeralSystem, value: str)
Args:
numeral_system: A previously defined custom numeral system.
value: The value (the number itself).
PROPRIÉTÉS:
init_value -> str
Returns the initial value the class was initialized with.
Méthodes:
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.
Itérate sur les numéros d'un système de système de chiffres personnalisé à partir du tout premier numéro (l'équivalent zéro) ou à partir d'un init_value donné.
Simule brièvement les anciens comptoirs de vitesse, comme l'ancien kilométrage des voitures.
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.
PROPRIÉTÉS:
combinations -> int
Returns the number of possible combinations (iterations).
La classe implémente le protocole de gestion de contexte Python.