J'ai lu "[Conversion mutuelle entre les nombres chinois et arabes] de @ xuyun19840618](http://qiita.com/xuyun19840618/items/a340f6dca5ef1cde7ac1)" et j'ai écrit ma propre implémentation dans les commentaires.
Quoi qu'il en soit, ne serait-il pas intéressant de pouvoir calculer avec des nombres chinois? Je pensais que c'était une classe.
Elle devient une sous-classe de la classe int afin qu'elle puisse être calculée.
L'instance int est immuable, donc la valeur doit être donnée dans la méthode __new__
.
Étant donné que le résultat du calcul ne sera pas affiché dans Kanji à moins qu'il ne soit à nouveau créé une instance de KanjiInt, la méthode de calcul est remplacée par KanjiInt. Comme il est difficile de définir la méthode une par une, la boucle for remplace les méthodes de l'opérateur de terme unique et de l'opérateur binaire.
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
class KanjiInt(int):
def __new__(cls, value=0):
arabic = kanji_to_int(value)
if isinstance(arabic, int):
value = arabic
return int.__new__(cls, value)
def __str__(self):
return int_to_kanji(self)
def __repr__(self):
return 'KanjiInt(%s)' % repr(str(self))
_unary = ('abs', 'inv', 'invert', 'neg', 'pos')
_binary = ('add', 'sub', 'mul', 'floordiv', 'mod', 'pow',
'and', 'or', 'xor', 'lshift', 'rshift')
for method in _unary:
exec('KanjiInt.__{0}__ = lambda self: KanjiInt(int.__{0}__(self))'.format(method))
for method in _binary:
exec('KanjiInt.__{0}__ = lambda self, value: KanjiInt(int.__{0}__(self, value))'.format(method))
unitlong = 'Tsunekawa', 'Un moine', 'Nayu et autres', 'Mystérieux', 'Un grand nombre incommensurable'
unit4 = ('',) + tuple('100 milliards de milliards de Kyoho') + unitlong
unit1 = ('',) + tuple('Dix mille')
digits = tuple('〇 1 2 3 4 5 6 7 8 9')
arabic4 = {unit[:1]: 10000**i for i, unit in enumerate(unit4)}
arabic1 = {unit: 10**i for i, unit in enumerate(unit1)}
arabics = {digit: i for i, digit in enumerate(digits)}
def int_to_kanji(arabic):
arabic = int(arabic)
if arabic == 0:
return digits[0]
sign = '-' if arabic < 0 else ''
arabic = abs(arabic)
def convert():
for column, digit in enumerate(map(int, str(arabic)[::-1])):
if column % 4 == 0 and (arabic // (10 ** column)) % 10000 != 0:
yield unit4[column // 4]
if digit != 0:
yield unit1[column % 4]
if digit != 1 or column % 4 == 0: #Mille,Cent,Sauf pour onze
yield digits[digit]
return sign + ''.join(list(convert())[::-1])
def kanji_to_int(kanji):
if not isinstance(kanji, str):
return 'error'
for longname in unitlong:
kanji = kanji.replace(longname, longname[0])
a0 = a1 = a4 = 0
for j in kanji:
if j in arabics:
a0 = a0 * 10 + arabics[j]
elif j in arabic1:
a1 += (a0 or 1) * arabic1[j]
a0 = 0
elif j in arabic4:
a4 += (a0 + a1 or 1) * arabic4[j]
a0 = a1 = 0
else:
return 'error'
return a0 + a1 + a4
if __name__ == '__main__':
value = KanjiInt('Cinquante six')
print("value =", value)
print('repr(value) =', repr(value))
print('str(value) =', str(value))
print('int(value) =', int(value))
print('abs(value) =', abs(value))
print('+value =', +value)
print('-value =', -value)
print('~value =', ~value)
print('value + 3 =', value + 3)
print('3 + value =', 3 + value)
print('value - 3 =', value - 3)
print('value * 3 =', value * 3)
print('value / 3 =', value / 3)
print('value // 3 =', value // 3)
print('value % 3 =', value % 3)
print('value ** 3 =', value ** 3)
print('value & 3 =', value & 3)
print('value | 3 =', value | 3)
print('value ^ 3 =', value ^ 3)
print('value << 3 =', value << 3)
print('value >> 3 =', value >> 3)
Résultat d'exécution
value =Cinquante six
repr(value) = KanjiInt('Cinquante six')
str(value) =Cinquante six
int(value) = 56
abs(value) =Cinquante six
+value =Cinquante six
-value = -Cinquante six
~value = -Cinquante sept
value + 3 =Cinquante neuf
3 + value = 59
value - 3 =Cinquante trois
value * 3 =168
value / 3 = 18.666666666666668
value // 3 =XVIII
value % 3 =deux
value ** 3 =175 616
value & 3 = 〇
value | 3 =Cinquante neuf
value ^ 3 =Cinquante neuf
value << 3 =448
value >> 3 =Sept
Recommended Posts