输入:阿拉伯数字(float或int型)
输出:金额的中文大写(字符串)
首先利用字符串的
maketrans
方法将阿拉伯数字与大写汉字进行映射,然后构造一个从个位到兆位的单位列表,对转换过后的数字列表进行反向遍历,依次与单位列表组合,就可以生成诸如(壹仟壹佰壹拾壹万)的字符串,之后对零项进行处理,这里我们将整数部分和小数部分分开处理,处理方式一样
1. 初始化参数
def __init__(self, num):
"""
:param num: 用户传入的数字
初始化参数,包括:
{
check_num :int/float 用作检查输入的数字
num:str 用作转换的阿拉伯数字字符串,排除`.00`的情况
trans_tab:dict 字符映射转换表
dec_label:list 小数部分的单位列表
int_label:list 整数部分的单位列表
int_string:str 整数部分构成的字符串
dec_string:str 小数部分构成的字符串
}
"""
# 去除00的情况
self.check_num = num
self.num = str(num).rstrip('.0')
self.trans_tab = str.maketrans('0123456789', '零壹贰叁肆伍陆柒捌玖')
self.dec_label = ['角', '分']
self.int_label = ['', '拾', '佰', '仟', '万', '拾', '佰', '千', '亿', '拾', '百', '千', '兆']
self.int_string = ''
self.dec_string = ''
2. 分离整数部分和小数部分
先调用字符串的
translate
将数字进行转换然后根据小数点进行分割
int_part, dec_part = self.num.translate(self.trans_tab).split('.')
3. 处理小数部分
首先针对小数部分的长度分别处理,然后将之与小数的单位列表按照对应索引组合,组合成类似·壹角壹分·的类型,如果最小位到了分,则需要将零角替换为零,若只有角则无需处理
# 对小数部分进行处理
if len(dec_part) == 2:
self.dec_string = ''.join([
dec_part[i] + self.dec_label[i] for i in range(len(dec_part))
]).replace('零角', '零')
else:
self.dec_string = ''.join([
dec_part[i] + self.dec_label[i] for i in range(len(dec_part))
])
4. 处理整数部分
这里注意,对整数部分的处理首先需要逆转整数数字的列表,从个位数字开始处理,这样能够有效的对数字的位数以及大小进行递增,从个十百千万依次递增(最大到兆),将整数部分与整数的单位列表所对应的的索引项相组合,若该数字为零则将组合后的结果也记为零,最后我们再将列表逆转回来并以字符串形式组合,将中间多余的零去除(若是一万零零零一则仅保留一个),最后对字符串尾部进行判断,如果结尾为零则表示最小位到十位,做补零操作,否则直接添加单位圆
# 处理整数部分
int_part = list(reversed(int_part))
int_list = list(reversed([
int_part[i] + self.int_label[i] if int_part[i] != '零' else '零' for i in range(len(int_part))
]))
if int_list[-1] == '零':
self.int_string = re.sub(r'零{2,}', '零', ''.join(int_list)).rstrip('零') + '圆零'
else:
self.int_string = re.sub(r'零{2,}', '零', ''.join(int_list)).rstrip('零') + '圆'
print(self.int_string + self.dec_string)
- 如果是浮点数,我们就需要组合两部分,若仅是纯整数,则只用处理整数部分,所以在初始化参数的时候定义了两个空字符串,这个时候就派上用场了
- 此外,我们需要判断一下数据的准确性,是否越界,是否是纯整数等等
def data_checker(self):
"""
判断用户传入的数据是否为数字类型且长度适中,最大仅支持到兆位,小数点后两位
:return: 数据无误则返回True,否则False
"""
if not isinstance(self.check_num, (int, float)):
return False
elif isinstance(self.check_num, int) and len(self.num) > 13:
return False
elif isinstance(self.check_num, float):
int_part, dec_part = str(self.check_num).split('.')
if len(int_part) > 13 or len(dec_part) > 2:
return False
return True