乐趣区

关于python:一个简单的中国亲戚关系计算器-实现思路整理

每年的春节,都会有一些本人简直没印象但父母就是很熟的亲戚,关系凌乱到你本人都说不清。
往年趁着春节在家没事件干,正好之前晓得有中国亲戚关系计算器,想着本人实现一下,特此记录。

算法实现与介绍

因为自己能力无限,只实现了基本功能 ….

需要

  • 计算亲戚关系链得出我应该怎么称说的后果

    数据定义

  1. 定义关系字符和修饰符

    【关系】f: 父,m: 母,h: 夫,w: 妻,s: 子,d: 女,xb: 兄弟,ob: 兄,lb: 弟,xs: 姐妹,os: 姐,ls: 妹【修饰符】&o: 年长,&l: 年幼,#: 隔断,[a|b]: 并列
  2. 关系对应数据汇合、关系过滤数据汇合(data.json 和 filter.json)

原来参考的作者的关系过滤数据汇合 json 有点问题,改了一下

filter 数据集的用处:比方 m,h 是我的妈妈的丈夫就是爸爸,也就是 f。filter 的作用是去重和简化,须要把 exp 用 str 进行替换

算法实现

须要解决的状况根本有以下三种:

我的爸爸 = 爸爸,

我的哥哥的弟弟 = 本人 / 弟弟 / 哥哥,

我的哥哥的老公 =?

剖析

三种后果:1. 单后果 2. 多后果 3. 谬误提醒,那么咱们的算法要兼容以上三种状况
上面咱们来一步步实现。

算法次要函数一:transformTitleToKey

该函数次要负责 将文字转换成关系符号

# 将文字转换成关系符号
def transformTitleToKey(text):
    result = text.replace("的", ",").replace("我", "").replace(" 爸爸 ","f").replace(" 妈妈 ","m").replace(" 老公 ","h").replace(" 老婆 ","w").replace(" 儿子 ","s").replace(" 女儿 ","d").replace(" 兄弟 ","xd").replace(" 哥哥 ","ob").replace(" 弟弟 ","lb").replace(" 姐妹 ","xs").replace(" 姐姐 ","os").replace(" 妹妹 ","ls").strip(",")
    return result

这里简化了原参考作者的写法,更 简略(不是) 合乎计算器设定

算法次要函数二:FilteHelper

该函数次要负责 去重和简化

# 去重和简化
def FilteHelper(text):
    result = text
    filterName = '/filter.json'  # filter.json 文件门路
    if not os.path.isfile(filterName):
        return "filterName 文件不存在"
    with open(filterName, "r") as f:
        obj = list(ijson.items(f, 'filter'))
    for i in range(len(obj[0])):
        users = obj[0][i]['exp']
        if re.match(obj[0][i]['exp'], result):  # 合乎正则
            result1 = re.findall(obj[0][i]['exp'], result)
            result = obj[0][i]['str']
            a = 0
            result2 = ""
            try:
                for i in result1:
                    result = result.replace("$" + str(a + 1), result1[a])
                    a = a + 1
                while result.find("#") != -1:
                    result_l = result
                    resultList = list(set(result_l.split("#")))  # # 是隔断符,所以宰割文本
                    for key in resultList:
                        result = FilteHelper(key)
                        if (result.find("#") == -1):  # 当关系符号不含 #时退出最终后果中
                            result2 = result2 + result
                return result2
            except Exception as e:
                return text
    return text

这里原参考作者解释的有点乱,我就以我个人见解参考着写了进去 … 能跑 …. 有错欢送指出
集体测试单后果,多后果都能实现,倡议多后果实现参考输入和代码具体了解

算法次要函数三:dataValueByKeys

该函数次要负责 从数据源中查找对应 key 的后果

# 从数据源中查找对应 key 的后果
def dataValueByKeys(data_text):
    dataName = '/data.json'  # data.json 文件门路
    if not os.path.isfile(dataName):
        return "data 文件不存在"
    fo = open(dataName, 'r', encoding='utf-8')
    ID_Data = demjson.decode(fo.read())
    fo.close()
    try:
        if ID_Data[data_text]:
            cityID = ID_Data[data_text]
            text = ""
            for key in cityID:
                text = text + key + '\\'
            return text.strip("\\")
        else:
            return "未找到"
    except Exception as e: # 解决多后果
        result = ""resultList = FilteHelper(strInsert(data_text, 0,',')).split(",")
        for key in resultList:
            result = result + dataValueByKeys(key)
        return result

输入与成果





根本达到成果

一些细节与已知问题

首先,是性别:如果‘我’是女性,那么‘我的父亲的儿子’能够为 [‘哥哥’,‘弟弟’],而不能够蕴含‘我’。(上述代码没实现)
另外,对于夫妻关系:在失常状况下,男性称呼只能够有‘妻子’,女性称呼只能够有‘丈夫’。(上述代码已实现)
第三,多种可能:‘我的父亲的儿子’能够是 [‘我’,‘哥哥’,‘弟弟’],再若是再往后计算,如‘我的父亲的儿子的儿子’,须要同时思考‘我的儿子’,‘哥哥的儿子’,‘弟弟的儿子’这三种可能。(上述代码已实现)
已知问题:某些波及本人的多重可能还存在莫名 BUG

源码

欢送 Star━(`∀´)ノ亻!
github

参考

站在伟人的肩膀上

hinese kinship system. 中国亲戚关系计算器 – 家庭称呼 / 称说计算 / 亲戚关系算法

算法次要参考了这个亲戚关系计算器

退出移动版