用python解决五格与起名问题
大二的暑假闲来无事,恰逢python自学刚刚入门,为了巩固知识,于是想通过python来解决日常生活中的一些问题。
关于姓名的学问——五格
如何取一个好听又好看的名字确实是一个难题。取名字的方法也是千奇百怪,数不胜数。在这里主要是通过五格的判断方法来取名字。主要参考资料为《姓名与人生》(高山翁译著),以及通过各种姓名五格测试网站来测试自动生成的姓名是否符合该要求。
主要步骤如下:
- 从网络上找到繁体字(五格计算必须)以及笔画的字库
- 找出好的五格搭配以及好的数理
- 输入姓
- 遍历字库与好的五格搭配中对比,得到姓名列表
- 在姓名列表中自行挑选喜欢的姓名组合
如何计算五格及其事理就不多说了,这些资料都可以通过网上的渠道找到。我们首先从第2步开始——找出好的五格搭配以及好的数理。
找出好的五格搭配以及好的数理
读取字典
每一笔画数的汉字列表已经分别装在30个不同的txt文件中。如1.txt的文件中装有“一”,“乙”的汉字,11.txt的文件中装有“国”,“寇”,“梗”等多个汉字。
def readfile(self):
# 将文件名字转换成路径
basedir = "fantizi\\"
lastdir = ".txt"
for i in range(30):
self.liebiao.append(basedir + str(i + 1) + lastdir)
# 读取文件并且创建字典
for i, filename in enumerate(self.liebiao):
self.zidian.setdefault(int(i + 1), [])
fp = open(filename, "r")
for line in fp:
word = line.split('、')
self.zidian[int(i + 1)] = word
for w in word:
self.fantizi.append(w)
其中self.liebiao表示文件名列表
self.zidian表示笔画数以及汉字的字典,如{1:[‘一’,‘乙’]}
self.fantizi表示字典库的所有汉字列表
定义好的五格以及五格搭配
这一部分主要是翻查资料,这里的代码看看就好了。比如说五格表示天格,地格,人格,总格,外格,这五格各自通过笔画数计算算式得出,五行也是由五格求出。下面预先定义的是好的五格、五行以及搭配。
# 所有数的好
self.good=[1,3,5,6,7,8,11,13,15,16,17,18,21,23,24,25,31,32,33,35,37,39,40,41,45,47,51,52,57,61,65,67,73,75,81]
#1,11,21,31,41,51,61,81
#32,52
#3,13,23,33,73
#24
#5,15,25,35,45,65,75
#6,16
#7,17,37,47,57,67
#8,18
#39
#40
# 人格搭配天格,地格,使用列表表示['木','火','水']'木'表示人格,'火'表示天格,'水'表示地格,1-2木,3-4火,5-6土,7-8金,9-10水
self.rengedapei={'木':{'木':['木','火','土'],'火':['木','火','土'],'水':['木','火','土']},
'火':{'木':['木','火','土'],'火':['木','火','土'],'土':['木','火','土']},
'土':{'火':['火','土','金'],'土':['火','土','金'],'金':['火','土','金']},
'金':{'土':['土'],'水':['土']}} #此搭配为吉搭配
#人格搭配外格renge5与waige5
self.waigedapei={1:[1,2,3,4,5,9,10],2:[1,3,4],3:[1,2,3,5,6],4:[1,2,5],5:[1,3,4,5,6,7,8],6:[1,3,5,7],7:[5,6,7,8,9],8:[1,5,6],9:[1,2,3,8]}
#天格人格地格搭配
self.tianrendige=[['木','木','木'],['木','木','火'],['木','木','土'],['木','火','木'],['木','火','土'],['木','水','木'],['火','木','木'],['火','木','火'],
['木', '木', '土'],['火','火','木'],['火','土','火'],['火','土','土'],['土','火','木'],['土','火','土'],['土','火','火'],['土','土','土'],
['土','土','金'],['土','金','木'],['金','土','土'],['金','土','金'],['金','金','土'],['水','木','土'],['金','水','金'],['水','金','土']]
计算五格
#计算天格
def caltiange(self):
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
# 如果单姓,便+1
if len(self.firstname) == 1:
if self.first == word:
self.tiange = wordss+1
#如果复姓,便复姓计算
if len(self.firstname) == 2:
if self.first == word:
self.tiange += wordss
if self.first2 == word:
self.tiange += wordss
#计算地格
def caldige(self,middle,last):
dige=0
#如果单姓双名,姓名的第二个字的笔画,加上第三个字的笔画
if last != '' :
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
dige+= wordss
if last == word:
dige+= wordss
#如果单姓单名,或复姓单名,姓名最后一个字的笔画加1
if len(self.firstname)==2 and last == None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
dige= wordss+1
return dige
# 计算人格
def calrenge(self,middle,last):
renge=0
#如果单姓单名
if len(self.firstname)==1 and last==None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
renge += wordss
if self.first == word:
renge += wordss
#如果单姓双名
if len(self.firstname)==1 and last!=None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
renge += wordss
if self.first == word:
renge += wordss
#如果复姓单名,复姓单名姓氏的第二个字加名的笔画
if len(self.firstname)==2 and last==None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if last == word:
renge += wordss
if self.first2 == word:
renge += wordss
#如果复姓双名,复姓复名姓氏的第二个字笔画加名的第一个字的笔画
if len(self.firstname)==2 and last!=None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
renge += wordss
if self.first2 == word:
renge += wordss
return renge
#计算总格,姓名笔画数的总和。
def calzongge(self,middle,last):
zongge=0
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
zongge += wordss
if self.first2 == word:
zongge += wordss
if last == word:
zongge += wordss
if self.first == word:
zongge += wordss
return zongge
#计算外格
def calwaige(self,middle,last):
waige=0
#复姓复名是姓的第一个字和名的最后一个字相加的笔画数
if len(self.firstname)==2 and last!=None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if last == word:
waige += wordss
if self.first == word:
waige += wordss
#复姓单名是复姓第一个字的笔画数加一
if len(self.firstname)==2 and last==None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if self.first == word:
waige = wordss+1
# 单姓复名是名的最后一个字的笔画加一
if len(self.firstname)==1 and last != None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if last == word:
waige = wordss+1
#单姓单名统一为二
if len(self.firstname) == 1 and last == None:
waige = 2
return waige
#给五格配上阴、阳五行
def calwuhang(self):
self.tiange5=str(self.tiange)[1]
self.tiange55 = self.calwuhang1(int(self.tiange5))
def calwuhang1(self,num):
wuge55=''
if num==1 or num==2:
wuge55 ='木'
if num==3 or num==4:
wuge55 ='火'
if num==5 or num==6:
wuge55 = '土'
if num==7 or num==8:
wuge55 = '金'
if num==0 or num==9 or num==10 :
wuge55 ='水'
return wuge55
其中命名格式,self.tiange表示该姓的天格数,self.tiange5表示该天格的对于五行的数,self.tiange55表示该天格所对应的五行(木火土金水),对于其他的dige,dige5,dige55等也是同样的命名方式。
而怎么知道是不是复姓,则需要以下的判断。
print("输入姓")
self.firstname = input()
if len(self.firstname) == 2:
self.first = self.firstname[0]
self.first2 = self.firstname[1]
else:
self.first = self.firstname
self.caltiange()
self.calwuhang()
print("姓为"+self.firstname+" 天格数为"+str(self.tiange)+" 五行数是"+str(self.tiange5)+" 五行是"+str(self.tiange55))
首先输入姓,然后判断姓的长度,如果长度为1则单姓,如果长度为2则复姓。
下面求出五格好搭配的方法
def findnum(self):
#首先拿到姓(拿到天格),第一个名字搭配姓,随后第二个名字搭配前两个字
#这几步求出姓,天格
print("输入姓")
self.firstname = input()
if len(self.firstname) == 2:
self.first = self.firstname[0]
self.first2 = self.firstname[1]
else:
self.first = self.firstname
self.caltiange()
self.calwuhang()
print("姓为"+self.firstname+" 天格数为"+str(self.tiange)+" 五行数是"+str(self.tiange5)+" 五行是"+str(self.tiange55))
#创建搭配列表
dapei=[]
#搭配数字列表
dapei2=[]
#搭配正确数字列表
dapei3=[]
#用天格人格地格搭配计算
for list in self.tianrendige:
#每一组合
if self.tiange55 == list[0]:
dapei.append([list[1],list[2]])
#dapei2用于五行换成五行数,如[1,2,5,6]表示人格木与地格土的五行数
x, y = self.calwuhangshu(list[1])
z,w = self.calwuhangshu(list[2])
dapei2=[x,y,z,w ]
#dapei3用于五行数中的正确搭配,如[[1,5]]表示人格木与地格土的五行数,[[2,5]]
dapei3.append([dapei2[0],dapei2[2]])
dapei3.append([dapei2[0],dapei2[3]])
dapei3.append([dapei2[1],dapei2[2]])
dapei3.append([dapei2[1],dapei2[3]])
#人格外格地格搭配,如[1,2,3]是人格木与外格木与地格火
dapei4=[]
#用人格外格搭配
for list in dapei3:
if list[0] in self.waigedapei.keys():
for num in self.waigedapei[list[0]]:
dapei4.append([list[0],num,list[1]])
#选择人格外格地格在good里面的数,注意为了不为int object is not iterable ,特意在24,39,40的位置加上94,99,90三个不可能达到的数字
#1,11,21,31,41,51,61,81
#32,52
#3,13,23,33,73
#24,94
#5,15,25,35,45,65,75
#6,16
#7,17,37,47,57,67
#8,18
#39,99
#40,90
renge={}
waige={}
dige={}
dapei5=[]
for list in dapei4:
renge=self.caldapei4(list[0])
waige=self.caldapei4(list[1])
dige=self.caldapei4(list[2])
try:
for i in renge:
for j in waige:
for k in dige:
dapei5.append([i,j,k])
except:
print("出现了nonetype得得得错误")
#去除94,99,90的错误
for list in dapei5:
if 94 or 99 or 90 in list:
dapei5.remove(list)
print(dapei5)
print(len(dapei5))
self.dapeigood = dapei5
def caldapei4(self,num):
if num == 1:
return 1,11,21,31,41,51,61,81
if num == 2:
return 32,52
if num == 3:
return 3,13,23,33,73
if num == 4:
return 4,94
if num == 5:
return 5,15,25,35,45,64,75
if num == 6:
return 6,16
if num == 7:
return 7,17,37,47,57,67
if num == 8:
return 8,18
if num == 9:
return 39,99
if num == 0:
return 40,90
def calwuhangshu(self,word):
if word == '木':
return 1,2
if word == '火':
return 3,4
if word == '土':
return 5,6
if word == '金':
return 7,8
if word == '水':
return 9,10
self.dapeigood保存着好的三个搭配。接下来需要用字库里的字与self.dapeigood的搭配组合对比,并且自动生成姓名组合
def getname(self):
name=set()
#计算双名
for middle in self.fantizi:
for last in self.fantizi:
dige=self.caldige(middle,last)
renge=self.calrenge(middle,last)
zongge=self.calzongge(middle,last)
waige=self.calwaige(middle,last)
#如果属于搭配5,则打印输出
for dd in self.dapeigood:
if renge==dd[0] and waige==dd[1] and dige==dd[2]:
name.add(self.firstname+middle+last)
#print(self.firstname+middle+last)
#计算单名
# for middle in self.fantizi:
# dige=self.caldige(middle,None)
# renge=self.calrenge(middle,None)
# zongge=self.calzongge(middle,None)
# waige=self.calwaige(middle,None)
# #如果属于搭配5,则打印输出
# for dd in self.dapeigood:
# if renge==dd[0]:
# print("ok1")
# if waige==dd[1]:
# print("ok2")
# if waige==dd[2]:
# print("ok3")
# print(str(dd[0])+" "+str(dd[1])+" "+str(dd[2]))
#if renge==dd[0] and waige==dd[1] and dige==dd[2]:
# name.add(self.firstname+middle)
print('名字有'+str(len(name)))
with open('goodgoodname.txt','w') as fp:
for n in name:
fp.write(n+' ')
fp.close()
最后便可以生成想要的姓名,如下框
输入姓
猪
姓为猪 天格数为17 五行数是7 五行是金
然后打开生成的文件,内容如下
猪乃杉 猪乃束 猪乃村 猪乃杞 猪乃步 猪乃汝 猪乃汐 猪乃池 猪乃私 猪乃秀 猪乃赤 猪乃足 猪乃身 猪乃车 猪乃辰
随便找一个名,在一个网站对该名进行测试。
比如说 猪乃身 可以达到86分。再找多几个名字来测试,可以发现的是,效果还可以。
反思
用到了大部分的五行判断方法,但里面的生肖之类的,和对于半好半坏的数理,都没有采用。还有关于人的性格这一块的预测,由于没有好坏的评价,难以判断,所以也没有添加上去。
技术刚入门,python的用法尚未熟悉,这些是需要好好改进滴!
以下是全部代码
#coding=gbk
class fanti():
def __init__(self):
self.fantizi=[]
#liebiao用于装文件名字
self.liebiao=[]
#创建的字典
self.zidian={}
self.first=''
self.first2=''
self.firstname = ''
self.lastname = ''
self.tiange=0
self.tiange5=0
self.tiange55=''
self.dapeigood = []
# 所有数的好
self.good=[1,3,5,6,7,8,11,13,15,16,17,18,21,23,24,25,31,32,33,35,37,39,40,41,45,47,51,52,57,61,65,67,73,75,81]
#1,11,21,31,41,51,61,81
#32,52
#3,13,23,33,73
#24
#5,15,25,35,45,65,75
#6,16
#7,17,37,47,57,67
#8,18
#39
#40
# 人格搭配天格,地格,使用列表表示['木','火','水']'木'表示人格,'火'表示天格,'水'表示地格,1-2木,3-4火,5-6土,7-8金,9-10水
self.rengedapei={'木':{'木':['木','火','土'],'火':['木','火','土'],'水':['木','火','土']},
'火':{'木':['木','火','土'],'火':['木','火','土'],'土':['木','火','土']},
'土':{'火':['火','土','金'],'土':['火','土','金'],'金':['火','土','金']},
'金':{'土':['土'],'水':['土']}} #此搭配为吉搭配的了啊
#人格搭配外格renge5与waige5
self.waigedapei={1:[1,2,3,4,5,9,10],2:[1,3,4],3:[1,2,3,5,6],4:[1,2,5],5:[1,3,4,5,6,7,8],6:[1,3,5,7],7:[5,6,7,8,9],8:[1,5,6],9:[1,2,3,8]}
#天格人格地格搭配
self.tianrendige=[['木','木','木'],['木','木','火'],['木','木','土'],['木','火','木'],['木','火','土'],['木','水','木'],['火','木','木'],['火','木','火'],
['木', '木', '土'],['火','火','木'],['火','土','火'],['火','土','土'],['土','火','木'],['土','火','土'],['土','火','火'],['土','土','土'],
['土','土','金'],['土','金','木'],['金','土','土'],['金','土','金'],['金','金','土'],['水','木','土'],['金','水','金'],['水','金','土']]
def readfile(self):
# 将文件名字转换成路径
basedir = "fantizi\\"
lastdir = ".txt"
for i in range(30):
self.liebiao.append(basedir + str(i + 1) + lastdir)
# 读取文件并且创建字典
for i, filename in enumerate(self.liebiao):
self.zidian.setdefault(int(i + 1), [])
fp = open(filename, "r")
for line in fp:
word = line.split('、')
self.zidian[int(i + 1)] = word
for w in word:
self.fantizi.append(w)
#计算天格
def caltiange(self):
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
# 如果单姓,便+1
if len(self.firstname) == 1:
if self.first == word:
self.tiange = wordss+1
#如果复姓,便复姓计算
if len(self.firstname) == 2:
if self.first == word:
self.tiange += wordss
if self.first2 == word:
self.tiange += wordss
#计算地格
def caldige(self,middle,last):
dige=0
#如果单姓双名,姓名的第二个字的笔画,加上第三个字的笔画
if last != '' :
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
dige+= wordss
if last == word:
dige+= wordss
#如果单姓单名,或复姓单名,姓名最后一个字的笔画加1
if len(self.firstname)==2 and last == None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
dige= wordss+1
return dige
# 计算人格
def calrenge(self,middle,last):
renge=0
#如果单姓单名
if len(self.firstname)==1 and last==None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
renge += wordss
if self.first == word:
renge += wordss
#如果单姓双名
if len(self.firstname)==1 and last!=None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
renge += wordss
if self.first == word:
renge += wordss
#如果复姓单名,复姓单名姓氏的第二个字加名的笔画
if len(self.firstname)==2 and last==None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if last == word:
renge += wordss
if self.first2 == word:
renge += wordss
#如果复姓双名,复姓复名姓氏的第二个字笔画加名的第一个字的笔画
if len(self.firstname)==2 and last!=None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
renge += wordss
if self.first2 == word:
renge += wordss
return renge
#计算总格,姓名笔画数的总和。
def calzongge(self,middle,last):
zongge=0
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if middle == word:
zongge += wordss
if self.first2 == word:
zongge += wordss
if last == word:
zongge += wordss
if self.first == word:
zongge += wordss
return zongge
#计算外格
def calwaige(self,middle,last):
waige=0
#复姓复名是姓的第一个字和名的最后一个字相加的笔画数
if len(self.firstname)==2 and last!=None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if last == word:
waige += wordss
if self.first == word:
waige += wordss
#复姓单名是复姓第一个字的笔画数加一
if len(self.firstname)==2 and last==None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if self.first == word:
waige = wordss+1
# 单姓复名是名的最后一个字的笔画加一
if len(self.firstname)==1 and last != None:
for wordss in self.zidian.keys():
for word in self.zidian[wordss]:
if last == word:
waige = wordss+1
#单姓单名统一为二
if len(self.firstname) == 1 and last == None:
waige = 2
return waige
#给五格配上阴、阳五行
def calwuhang(self):
self.tiange5=str(self.tiange)[1]
self.tiange55 = self.calwuhang1(int(self.tiange5))
def calwuhang1(self,num):
wuge55=''
if num==1 or num==2:
wuge55 ='木'
if num==3 or num==4:
wuge55 ='火'
if num==5 or num==6:
wuge55 = '土'
if num==7 or num==8:
wuge55 = '金'
if num==0 or num==9 or num==10 :
wuge55 ='水'
return wuge55
def findnum(self):
#首先拿到姓(拿到天格),第一个名字搭配姓,随后第二个名字搭配前两个字
#这几步求出姓,天格
print("输入姓")
self.firstname = input()
if len(self.firstname) == 2:
self.first = self.firstname[0]
self.first2 = self.firstname[1]
else:
self.first = self.firstname
self.caltiange()
self.calwuhang()
print("姓为"+self.firstname+" 天格数为"+str(self.tiange)+" 五行数是"+str(self.tiange5)+" 五行是"+str(self.tiange55))
#创建搭配列表
dapei=[]
#搭配数字列表
dapei2=[]
#搭配正确数字列表
dapei3=[]
#用天格人格地格搭配计算
for list in self.tianrendige:
#每一组合
if self.tiange55 == list[0]:
dapei.append([list[1],list[2]])
#dapei2用于五行换成五行数,如[1,2,5,6]表示人格木与地格土的五行数
x, y = self.calwuhangshu(list[1])
z,w = self.calwuhangshu(list[2])
dapei2=[x,y,z,w ]
#dapei3用于五行数中的正确搭配,如[[1,5]]表示人格木与地格土的五行数,[[2,5]]
dapei3.append([dapei2[0],dapei2[2]])
dapei3.append([dapei2[0],dapei2[3]])
dapei3.append([dapei2[1],dapei2[2]])
dapei3.append([dapei2[1],dapei2[3]])
#人格外格地格搭配,如[1,2,3]是人格木与外格木与地格火
dapei4=[]
#用人格外格搭配
for list in dapei3:
if list[0] in self.waigedapei.keys():
for num in self.waigedapei[list[0]]:
dapei4.append([list[0],num,list[1]])
#选择人格外格地格在good里面的数,注意为了不为int object is not iterable ,特意在24,39,40的位置加上94,99,90三个不可能达到的数字
#1,11,21,31,41,51,61,81
#32,52
#3,13,23,33,73
#24,94
#5,15,25,35,45,65,75
#6,16
#7,17,37,47,57,67
#8,18
#39,99
#40,90
renge={}
waige={}
dige={}
dapei5=[]
for list in dapei4:
renge=self.caldapei4(list[0])
waige=self.caldapei4(list[1])
dige=self.caldapei4(list[2])
try:
for i in renge:
for j in waige:
for k in dige:
dapei5.append([i,j,k])
except:
print("出现了nonetype得得得错误")
#去除94,99,90的错误
for list in dapei5:
if 94 or 99 or 90 in list:
dapei5.remove(list)
print(dapei5)
print(len(dapei5))
self.dapeigood = dapei5
def caldapei4(self,num):
if num == 1:
return 1,11,21,31,41,51,61,81
if num == 2:
return 32,52
if num == 3:
return 3,13,23,33,73
if num == 4:
return 4,94
if num == 5:
return 5,15,25,35,45,64,75
if num == 6:
return 6,16
if num == 7:
return 7,17,37,47,57,67
if num == 8:
return 8,18
if num == 9:
return 39,99
if num == 0:
return 40,90
def calwuhangshu(self,word):
if word == '木':
return 1,2
if word == '火':
return 3,4
if word == '土':
return 5,6
if word == '金':
return 7,8
if word == '水':
return 9,10
# 为每个汉字及其搭配进行求人格,总格,外格,地格,
def getname(self):
fp = open('goodgoodname.txt', 'w')
name=set()
#计算双名
for middle in self.fantizi:
for last in self.fantizi:
dige=self.caldige(middle,last)
renge=self.calrenge(middle,last)
zongge=self.calzongge(middle,last)
waige=self.calwaige(middle,last)
#如果属于搭配5,则打印输出
for dd in self.dapeigood:
if renge==dd[0] and waige==dd[1] and dige==dd[2]:
name.add(self.firstname+middle+last)
#print(self.firstname+middle+last)
fp.write(self.firstname+middle+last+" ")
fp.close()
#计算单名
# for middle in self.fantizi:
# dige=self.caldige(middle,None)
# renge=self.calrenge(middle,None)
# zongge=self.calzongge(middle,None)
# waige=self.calwaige(middle,None)
# #如果属于搭配5,则打印输出
# for dd in self.dapeigood:
# if renge==dd[0]:
# print("ok1")
# if waige==dd[1]:
# print("ok2")
# if waige==dd[2]:
# print("ok3")
# print(str(dd[0])+" "+str(dd[1])+" "+str(dd[2]))
#if renge==dd[0] and waige==dd[1] and dige==dd[2]:
# name.add(self.firstname+middle)
# print('名字有'+str(len(name)))
#with open('goodgoodname.txt','w') as fp:
# for n in name:
# fp.write(n+' ')
# fp.close()
if __name__ =="__main__":
fan = fanti()
fan.readfile()
fan.findnum()
fan.getname()
print(fan.fantizi)